多路io复用时gcc编译出现段错误

guolele2010 2010-09-16 04:13:50

#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编译出现了段错误
谁能帮我找找原因?
...全文
143 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
wwwunix 2010-09-17
  • 打赏
  • 举报
回复
把报错信息贴出来。
justkk 2010-09-17
  • 打赏
  • 举报
回复
代码太长了,最好自己先精简一下,隔离一下问题..
guolele2010 2010-09-16
  • 打赏
  • 举报
回复
运行时,好像打错了,不好意思
justkk 2010-09-16
  • 打赏
  • 举报
回复
编译的时候出现段错误?还是在运行的时候?
job82824 2010-09-16
  • 打赏
  • 举报
回复
段错误好像是数组的地址非法了。比如说分派一个内存地址
void *pp1 = myAlloc();
然后分派失败了,即
pp1==NULLL;
但是你没有检验就直接拿来使用了。比如
pp1[m]=value1;
这时候就是段错误了。
代码太长了,有空帮你调调看:)
guolele2010 2010-09-16
  • 打赏
  • 举报
回复
代码好像有点长,不过我已经尽量用自己语言解释了一下,有错误一定要指出,辛苦了

19,615

社区成员

发帖
与我相关
我的任务
社区描述
系统使用、管理、维护问题。可以是Ubuntu, Fedora, Unix等等
社区管理员
  • 系统维护与使用区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧