linux socket服务器问题,求大神详细解释下程序运行过程,代码如下~
在网上看了这个程序,服务器端可以接收多个客户端传来的信息,并且可以判断是否有新连接、连接数目、是否达到最大连接数等,小女子不才,函数的作用和代码差不多理解了,但就是想不了服务器是怎么运行的,流程是怎样的理不清思路,还希望各位大神们能抽空看一下这个程序,能详细解释下运行流程,最好再有相关代码的解释,十分感谢!!!!!
程序代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<unistd.h>
#include<string.h>
#include<netinet/in.h>
#include<netdb.h>
#include<arpa/inet.h>
#define PORT 1205
#define MAXNUM 3
#define MAXSIZE 1024
int fd[MAXNUM];//
int connect_num;
void showclient()
{
int i;
printf("client amount: %d\n", connect_num);
for (i = 0; i <MAXNUM; i++) {
printf("[%d]:%d ", i, fd [i]);
}
printf("\n\n");
}
int main()
{
struct sockaddr_in server;
struct sockaddr_in client;
bzero(&server,sizeof(server));
bzero(&client,sizeof(client));
char buf[MAXSIZE];
int sock_fd=socket(AF_INET,SOCK_STREAM,0);
if(sock_fd==-1)
{
print(“socket failed!\n”);
exit(-1);
}
server.sin_family=AF_INET;
server.sin_port=htons(PORT);
server.sin_addr=htons(“192.168.2.4”);
int bind_fd=bind(sock_fd, (struct sockaddr*)server,sizeof(server));
if(bind_fd==-1)
{
printf(“bind failed!\n”);
exit(-1);
}
int listen_fd=listen(sock_fd,MAXNUM);
if(listen_fd==-1)
{
printf(“listen failed!\n”);
exit(-1);
}
printf(“listen port:%d\n”,PORT);
}
fd_set fdsr;
int maxsock;
struct timeval tv;
connect_num= 0;
sin_size = sizeof(client_addr);
maxsock = sock_fd;//??
while (1) {
// 初始化文件描述符集合
FD_ZERO(&fdsr);
FD_SET(sock_fd, &fdsr);
// timeout setting
tv.tv_sec = 30;
tv.tv_usec = 0;
for (i = 0; i < MAXNUM; i++) {
if (fd [i] != 0) {
FD_SET(fd [i], &fdsr);
}
}
ret = select(maxsock + 1, &fdsr, NULL, NULL, &tv);
if (ret < 0) {
perror("select");
break;
} //select失败
else if (ret == 0) {
printf("timeout\n");
continue;
for (i = 0; i < connect_num; i++) {
if (FD_ISSET(fd [i], &fdsr)) {
ret = recv(fd [i], buf, sizeof(buf), 0);
if (ret <= 0) { // client close
printf("client[%d] close\n", i);
close(fd[i]);
FD_CLR(fd[i], &fdsr);
fd[i] = 0;
} else { // receive data
if (ret < MAXSIZE)
memset(&buf[ret], '\0', 1);
printf("client[%d] send:%s\n", i, buf);
}
}
}
if (FD_ISSET(sock_fd, &fdsr)) {
new_fd = accept(sock_fd, (struct sockaddr *)&client_addr, &sin_size);
if (new_fd <= 0) {
perror("accept");
continue;
}
if (conn_amount <MAXNUM) {
fd[connect_num++] = new_fd;
printf("new connection client[%d] %s:%d\n", connect_num,
inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
if (new_fd > maxsock)
maxsock = new_fd;
}
else {
printf("max connections arrive, exit\n");
send(new_fd, "bye", 4, 0);
close(new_fd);
break;
}
}
showclient();
}
for (i = 0; i < MAXNUM; i++) {
if (fd[i] != 0) {
close(fd[i]);
}
}
exit(0);
}
[解决办法]
大概看了下,就是把接收到的客户端连接(描述符)保存在fd_A中,用select监控多个套接口的状态,循环完成:
监控fd_A中套接字的可读状态;
有可读的客户端套接字时,读取信息;
有客户端连接时接收新的客户端连接;
客户端连接没有超过上限时,加入到fd_A中;
[解决办法]
ok,这个代码没问题了。前面应该是少复制了一个"}"。
fd_A[BACKLOG]数据里面保存所有已连接套接字,如果元素值为0,表示这个元素还未被使用,conn_amount记录了当前的连接总数。
while(1)前面的代码应该都能看懂吧!while(1)里面,select调用前,前面的所有代码都是为了调用select做的准备,即设置好fd_set。select后面,根据返回值ret,如果ret<0表示select调用出错了,所以直接break结束循环;如果返回0标识超时,continue接着下次循环;如果返回大于0,程序首先判断所有已连接套接字,是否有数据可读,有的话就读出来然后打印。这步做完之后,接着判断监听套接字(sockfd)是否可读,如果可读表示有新的连接到来,如果连接数没满就加到fd_A,如果满了就break(这里有问题,连接数一旦满了服务器进程就结束了)。