计算机与信息工程学院 09级嵌入式 吴素芬
server-client之间的通信
/*********************************server.c************************************************/
#include
#include
#include
#include
#include "wrap.h"
#define MAXLINE 80
#define SERV_PORT 8000
int main(int argc, char **argv)
{
int i, maxi, maxfd, listenfd, connfd, sockfd;
int nready, client[FD_SETSIZE];
ssize_t n;
fd_set rset, allset;
char buf[MAXLINE];
char str[INET_ADDRSTRLEN];
socklen_t cliaddr_len;
struct sockaddr_in cliaddr, servaddr;
int j;
listenfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
Bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
Listen(listenfd, 20);
maxfd = listenfd; /* initialize */
maxi = -1; /* index into client[] array */
for (i = 0; i < FD_SETSIZE; i++)
client[i] = -1; /* -1 indicates available entry */
FD_ZERO(&allset);
FD_SET(listenfd, &allset);
for (;;) {
rset = allset; /* structure assignment */
nready = select(maxfd + 1, &rset, NULL, NULL, NULL);
if (nready < 0)
perr_exit("select error");
if (FD_ISSET(listenfd, &rset)) { /* new client connection */
cliaddr_len = sizeof(cliaddr);
connfd = Accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len);
printf("received from %s at PORT %d\n", inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)), ntohs(cliaddr.sin_port));
for (i = 0; i < FD_SETSIZE; i++)
if (client[i] < 0) {
client[i] = connfd; /* save descriptor */
break;
}
if (i == FD_SETSIZE) {
fputs("too many clients\n", stderr);
exit(1);
}
FD_SET(connfd, &allset); /* add new descriptor to set */
if (connfd > maxfd)
maxfd = connfd; /* for select */
if (i > maxi)
maxi = i; /* max index in client[] array */
if (--nready == 0)
continue; /* no more readable descriptors */
}
for (i = 0; i <= maxi; i++) { /* check all clients for data */
if ((sockfd = client[i]) < 0)
continue;
if (FD_ISSET(sockfd, &rset)) {
if ((n = Read(sockfd, buf, MAXLINE)) < 0) { //读取客户端发送的内容
/*connection closed by client */
Close(sockfd); //如果读取失败则关闭连接
FD_CLR(sockfd, &allset); //把这个文件描述符从连接中清除
client[i] = -1; //把客户端标志设为-1
} else {
for (j = 0; j <= maxi; j++) {
if (FD_ISSET(sockfd, &rset))
{
if(sockfd!=client[j]);
Write(client[j], buf, n);
}
//把已读到的数据发送给每一个连接的客户端
}
}
if (--nready == 0)
break; /* no more readable descriptors */
}
}
}
}
/********************************client.c ****************/
#include
#include
#include
#include
#include "wrap.h"
#include
#include
#include
#define MAXLINE 80
#define SERV_PORT 8000
int main(int argc, char *argv[])
{
struct sockaddr_in servaddr;
char buf[MAXLINE];
int sockfd, n;
pid_t pid;
sockfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);
servaddr.sin_port = htons(SERV_PORT);
Connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
pid = fork(); //分支为两个进程
if (pid > 0) { //父进程
while (fgets(buf, MAXLINE, stdin) != NULL) {
Write(sockfd, buf, strlen(buf)); //向客户端发送数据
}
}
if (pid == 0) { //子进程
int b_on = 1;
ioctl(sockfd, FIONBIO, &b_on);
for (;;)
if ((n = Read(sockfd, buf, MAXLINE)) > 0) //向服务器接收数据
Write(STDOUT_FILENO, buf, n); //把读到的数据写进标准输出
}
Close(sockfd);
return 0;
}
/*server执行过程如下:
[root@localhost ~]# cd Desktop/
[root@localhost Desktop]# gcc server.c -o server
[root@localhost Desktop]# ./server
received from 127.0.0.1 at PORT 47595 客户端连接上服务器
received from 127.0.0.1 at PORT 47596
cliect执行过程如下:
在客户端中输入内容,回车后在内容回显到各个客户端中
第一个客户端
[root@localhost ~]# cd Desktop/
[root@localhost Desktop]# gcc client.c -o client
[root@localhost Desktop]# ./client
hello
hello
nihao
nihao
fen
fen
第二个客户端
[root@localhost ~]# cd Desktop/
[root@localhost Desktop]# ./client
hello
nihao
fen