#include<stdio.h>
#include<string.h>
#include<sys/socket.h>
#include<sys/select.h>
#include<sys/types.h>
#include<netinet/in.h>
#include <fcntl.h>
#include<errno.h>
#include<unistd.h>
#include <sys/stat.h>
#include<stdlib.h>
#define MAX_CONNECT_NUM 50
#define MAX_LISTEN_NUM 10
#define PORTNUMBER 3030
#define MAX_RWSIZE 1024
struct connect_wholemsg
{
int from_socketfd; // 服务器监听进程的socket描述符
int connect_room;//还可以连接的空间/数目
struct connect_info//接连的信息
{
int fd;//打开的文件描述符,用于添加到select函数宏定义里读、写监视文件描述符集中,以及贮存信息
int sd;//accept上的描述符
}connect_msg[MAX_CONNECT_NUM];
};
int acceptop(struct connect_wholemsg *conn_whomsg)//要使用指针,所以后面指定时要用->但是指定fd、sd就用.
{
int acceptfd;
int i,flag;
acceptfd = accept(conn_whomsg->from_socketfd,NULL,NULL);
if(acceptfd == -1)
{
printf("server:acceptfd erro\n");
return(0);
}
else
{
/*非阻塞套接字*/
flag = fcntl(conn_whomsg->from_socketfd,F_GETFL,0);
fcntl(conn_whomsg->from_socketfd,F_SETFL,flag | O_NONBLOCK);
/*往第一个空的空间写入连接的信息*/
for(i = 0;i < MAX_CONNECT_NUM;i++)
{
if(conn_whomsg->connect_msg[i].sd < 0)
{
break;
}
}
conn_whomsg->connect_msg[i].sd = acceptfd;//写入连接套接字描述符
conn_whomsg->connect_room--;
}
return(1);
}
int recieveop_num(struct connect_wholemsg *conn_wholemsg,int i)
{
int n;
char buffer[MAX_RWSIZE];
int buffd,n_byte;
if((n_byte = read(conn_wholemsg->connect_msg[i].sd,buffer,MAX_RWSIZE)) < 0)
{
printf("server:read msg erro\n");
return 0;
}
buffer[n_byte] = '\0';
printf("here are you\n");
buffd = open(buffer,O_RDONLY);//将读到的内容返回成文件描述符,贮存在buffd里
if(buffd < 0)
{
close(conn_wholemsg->connect_msg[i].sd);
conn_wholemsg->connect_msg[i].sd = -1;
conn_wholemsg->connect_msg[i].fd = -1;
conn_wholemsg->connect_room++;
return 0;
}
conn_wholemsg->connect_msg[i].fd = buffd;
printf("server:reccept msg is:%s\n",buffer);
return 1;
}
int writeop_num(struct connect_wholemsg *conn_wholemsg,int i)//向客户端返回它输入的信息
{
int n;
char buffer[MAX_RWSIZE];
int buffd,w_byte;
w_byte = read(conn_wholemsg->connect_msg[i].fd,buffer,MAX_RWSIZE);
printf("here are you\n");
if(w_byte < 0)
{
close(conn_wholemsg->connect_msg[i].sd);
close(conn_wholemsg->connect_msg[i].fd);
conn_wholemsg->connect_msg[i].sd = -1;
conn_wholemsg->connect_msg[i].fd = -1;
conn_wholemsg->connect_room++;
return 0;
}
w_byte = write(conn_wholemsg->connect_msg[i].sd,buffer,MAX_RWSIZE);
if(w_byte < 0)
{
printf("server:write erron\n");
return 0;
}
conn_wholemsg->connect_room--;
return 1;
}
int main(void)
{
int server_listenfd;
struct sockaddr_in listen_addr;
struct connect_wholemsg conn_wholemsg;
int n,flag,addrlen;
fd_set rfds,wfds;
int maxfd;
int select_num;
/*创建socket*/
if((server_listenfd = socket(AF_INET,SOCK_STREAM,0)) == -1)
{
printf("server:creat socket erron\n");
exit(0);
}
printf("server:create socket\n");
/*设置绑定*/
bzero(&listen_addr,sizeof(struct sockaddr_in));
listen_addr.sin_family = AF_INET;
listen_addr.sin_port = htons(PORTNUMBER);
listen_addr.sin_addr.s_addr = htonl(INADDR_ANY);
/*设置成下次快速启动服务器*/
n = 1;
setsockopt(server_listenfd,SOL_SOCKET,SO_REUSEADDR,&n,sizeof(int));
/*将(server_listenfd设定成非阻塞*/
flag = fcntl(server_listenfd,F_GETFL,0);
fcntl(server_listenfd,F_SETFL,flag | O_NONBLOCK);
/*绑定*/
addrlen = sizeof(struct sockaddr);
if(bind(server_listenfd,(struct sockaddr *)&listen_addr,addrlen) == -1)
{
printf("server:bind erro\n");
exit(0);
}
printf("server:bind socket\n");
/*监听*/
listen(server_listenfd,MAX_LISTEN_NUM);
printf("server:listen socket\n");
/*重置连接贮存信息*/
conn_wholemsg.from_socketfd = server_listenfd;
conn_wholemsg.connect_room = MAX_CONNECT_NUM;
for(n = 0;n < MAX_CONNECT_NUM;n++)//清空连接
{
conn_wholemsg.connect_msg[n].fd = -1;
conn_wholemsg.connect_msg[n].sd = -1;
}
FD_ZERO(&rfds);
FD_ZERO(&wfds);
while(1)
{
maxfd = 0;
if(conn_wholemsg.connect_room > 0)//有可用空间,就准备select那个监听套接字
{
FD_SET(conn_wholemsg.from_socketfd,&rfds);
maxfd = conn_wholemsg.from_socketfd;
}
for(n = 0;n < MAX_CONNECT_NUM;n++)
{
if(conn_wholemsg.connect_msg[n].sd > 0)//连接上的用户端贮存空间
{
if(conn_wholemsg.connect_msg[n].fd > 0)
{
FD_SET(conn_wholemsg.connect_msg[n].fd,&wfds);
}
else
{
FD_SET(conn_wholemsg.connect_msg[n].fd,&rfds);//段错误
/*printf("server:not here...\n");
close(server_listenfd);
exit(1);*/
}
maxfd = maxfd > conn_wholemsg.connect_msg[n].fd ? maxfd : conn_wholemsg.connect_msg[n].fd;
printf("maxfd is %d\n",maxfd);
}
}
printf("server:waitting for...\n");
select_num = select(maxfd + 1,&rfds,&wfds,NULL,0);
printf("server:the select_num is%d\n",select_num);
if(select_num > 0)//有文件符操作活动
{
if(FD_ISSET(conn_wholemsg.from_socketfd,&rfds))//有写活动
{
acceptop(&conn_wholemsg);//开始连接客户端
select_num--;
}
for(n = 0;(n<MAX_CONNECT_NUM)&&(select_num>0);n++)//检查其它连接有无读活动
{
if(FD_ISSET(conn_wholemsg.connect_msg[n].fd,&rfds))
{
recieveop_num(&conn_wholemsg,n);//有就执行函数操作
select_num--;
}
}
for(n = 0;(n < MAX_CONNECT_NUM) && (select_num > 0);n++)//检查其它连接有无写活动
{
if(FD_ISSET(conn_wholemsg.connect_msg[n].fd,&wfds))
{
writeop_num(&conn_wholemsg,n);//有就执行函数操作
select_num--;
}
}
}
}
close(server_listenfd);
exit(1);
}
-------------------------------------------------------
上面的代码在
FD_SET(conn_wholemsg.connect_msg[n].fd,&rfds);//段错误
/*printf("server:not here...\n");
close(server_listenfd);
exit(1);*/
这段代码里,gcc编译出现了段错误
谁能帮我找找原因?