读书人

高手们看看这个c程序错在哪解决有关

发布时间: 2012-03-31 13:13:26 作者: rapoo

高手们看看这个c程序错在哪,解决问题马上给分(虽然不多)!
目的:当一个client上传数据,server将组播到所有连接的用户。
程序中又两次fork(),第一次是用来做并发服务器的,第二次的子进程用来循环检测ctrlist数组。

#define SERVERPORT 7077

typedef struct {
char occupied[10];
int procid;
int modifying;
int sendtothers;
}ctrlist;

int shmid,shmid2;
int main()
{
int s_fd,bdret,lisnret,new_fd;
struct sockaddr_in srv_addr;
char *addr;
char *addr2;
char *combuf;
ctrlist *cl;
pid_t pid,pid2;

shmid = shmget(IPC_PRIVATE,10*sizeof(ctrlist),IPC_CREAT|0777);
shmid2 = shmget(IPC_PRIVATE,1024*1024*sizeof(char),IPC_CREAT|0777);
s_fd = socket(AF_INET,SOCK_STREAM,0);

if(s_fd < 0)
{
printf( "Socket error!!\n ");
exit(1);
}

bzero(&srv_addr,sizeof(srv_addr));
srv_addr.sin_family = AF_INET;
srv_addr.sin_port = htons(SERVERPORT);
srv_addr.sin_addr.s_addr = inet_addr( "172.18.128.179 ");
int n = 1;
setsockopt(s_fd,SOL_SOCKET,SO_REUSEADDR,&n,sizeof(int));

bdret = bind(s_fd,(struct sockaddr*)&srv_addr,sizeof(srv_addr));
if(bdret < 0)
{
printf( "Bind error!!\n ");
exit(1);
}
lisnret = listen(s_fd,5);
char buffer[1024];
bzero(buffer,1024);
int first=0;
while(1)
{
first++;

new_fd = accept(s_fd,NULL,NULL);
if(new_fd < 0)
{
printf( "Accept Error : %s!!\n ",strerror(errno));
}
//创建进程
if((pid = fork()))//父进程(1)重新监听端口
{
printf( "first = %d\n ",first);
printf( "first fork(father): %d\n ",getpid());
close(new_fd);
}
else if(pid < 0)
printf( "Fork Error : %s!!\n ",strerror(errno));
else//子进程(1)
{
printf( "first fork(child): %d\n ",getpid());
addr=shmat(shmid,0,0);
cl = (ctrlist*)addr;
int k;
for(k = 0;k < 10;k++)//找到一个空位,并填充信息
if(strncmp(cl[k].occupied, "_+&%ocup+ ",9) == 0)
k++;
else {
strcpy(cl[k].occupied, "_+&%ocup+ ");
cl[k].procid = getpid();
if(first == 1)
cl[k].modifying = 1;
else cl[k].modifying = 0;
cl[k].sendtothers = 0;
break;


}
printf( "Next will fork , create process(2)\n ");
//再次创建进程(2)
if((pid2 = fork()) == 1){//f进程与客户端交互
printf( "second fork(father): %d\n ",getpid());
close(s_fd);
char buffer[1024*1024];
bzero(buffer,1024*1024);
while(1) {
n = read(new_fd,buffer,1024*1024);
if(!n)
{
break;
}
buffer[n] = 0;
printf( "收到信息: %s\n ",buffer);
if(!strncmp(buffer, "_+&%[modifyapplication]%&+_ ",sizeof( "_+&%[modifyapplication]%&+_ "))){
printf( "提交修改申请\n ");
addr = shmat(shmid,0,0);
cl = (ctrlist*)addr;
int k = 0;
for(;k < 10;k++){
if(cl[k].modifying == 1)break;
}
if(k == 10)
{
printf( "提交修改请求被允许\n ");
strcpy(buffer, "_+&%[modifypermitted]%&+_ ");
write(new_fd,buffer,strlen(buffer));
}
else {
printf( "提交修改请求被拒绝\n ");
strcpy(buffer, "_+&%[modifyunpermitted]%&+_ ");
write(new_fd,buffer,strlen(buffer));
}

}else {
//如果buffer中没有表示字段,说明传入的是正文,则将buffer拷贝到combuf中,然后将该进程对应的结构体的sendtothers字段置1
addr2 = shmat(shmid2,0,0);
combuf = (char*)addr2;
strcpy(combuf,buffer);
//下面查找所在位置的父进程的节点
printf( "combuf : %s\n ",combuf);
addr = shmat(shmid,0,0);
cl = (ctrlist*)addr;
int k,idd = getpid();
for(k = 0 ;k < 10;k++)
if(cl[k].procid != idd && (strncmp(cl[k].occupied, "_+&%ocup+ ",sizeof( "_+&%ocup+ ")) == 0)){
cl[k].sendtothers = 1;
break;
}
}
}
close(new_fd);
exit(0);
}else if(pid2 == 0){//c进程(2):循环检测是否需要组播
printf( "second fork(child): %d\n ",getpid());
addr=shmat(shmid,0,0);
cl = (ctrlist*)addr;
ctrlist *tmp;
int k,id=getppid();
printf( "循环检测 : %d\n ",id);
for(k = 0;k <10;k++)
if(cl[k].procid == id){
tmp = &cl[k];
break;
}
for(k = 0;k <10;k++)
if(strncmp(cl[k].occupied, "_+&%ocup+ ",sizeof( "_+&%ocup+ "))==0)


printf( "struct:\n %s\t%d\t%d\t%d\n ",tmp-> occupied,tmp-> procid,tmp-> modifying,tmp-> sendtothers);

while(1){
if(tmp-> sendtothers && tmp-> modifying == 0){
addr2 = shmat(shmid2,0,0);
combuf = (char*)addr2;
write(new_fd,combuf,strlen(buffer));
tmp-> sendtothers = 0;
}
}
}
}
}

}

[解决办法]
LZ的代码书写比较乱。
还有请把错误提示贴出来

读书人网 >C语言

热点推荐