user-0 提问: linux下用C语言写的聊天程序中的一个问题

回复:
user: user-1
content: 不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊！ http://topic.csdn.net/u/20120210/09/51109ed0-07b9-41f2-b487-a51597f2ca01.html

user: user-2
content: 你没有判断fork返回值，根据返回值确定是主进程还是子进程。 你的 if(!fork()) 这样创建下来 主进程和子进程都进入下面的代码段中。

user: user-0
content: 多谢提醒，当时也确实考虑过包体的定义问题，不过我这里是write错误，接发消息应该没有问题。。  引用 7 楼 zhao4zhong1 的回复:不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊！ http://topic.csdn.net/u/20120210/09/51109ed0-07b9-41f2-b487-a51597f2ca01.html

user: user-0
content: 当执行if(!fork())时，说明!fork()值为真，也就是非0，那fork()的值肯定就是0了，这样下面执行的就是子进程啊。。  引用 6 楼 carlos1520 的回复:你没有判断fork返回值，根据返回值确定是主进程还是子进程。 你的 if(!fork()) 这样创建下来 主进程和子进程都进入下面的代码段中。

user: user-0
content: 由于时间比较紧张，代码还有很多需要完善的地方，大家先帮忙看看吧

user: user-0
content: 客户端代码  #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h>		//基本系统数据类型 #include <sys/socket.h>		//提供socket函数和相关数据结构 #include <netinet/in.h>		//定义了数据结构struct sockaddr_in; #include <unistd.h>			//提供通用的文件、目录、程序和进程操作的函数 #include <errno.h>			//处理出错机制 #include <netinet/tcp.h>    #define MAXDATASIZE 128 #define PORT 3000 static int sockfd;  int main(int argc, char ** argv) { 	int sockfd,nbytes; 	char buf[MAXDATASIZE]; 	char name[10],password[10],str[50],s1[50]; 	 	struct sockaddr_in srvaddr,clientaddr; 	 	char *p,*p1,*p2; 	char bufp[10]; 	char mes[1024];  	 	if (argc != 2) 	{ 		printf ("Usage error\n"); 		exit(1); 	} 	 	//创建套接字 	sockfd = socket(AF_INET,SOCK_STREAM,0); 	if(sockfd == -1) 	{ 		printf ("can not create socket\n"); 		exit(1); 	} 	 	//分配服务器的套接字地址 	bzero(&srvaddr,sizeof(srvaddr)); 	srvaddr.sin_family = AF_INET; 	srvaddr.sin_port = htons(PORT); 	if (inet_aton("127.0.0.1",&srvaddr.sin_addr) == 0) 	{ 		printf ("addr convert error\n"); 		exit(1); 	} 	 	//对远程服务器发起连接请求 	if(connect(sockfd,(struct sockaddr *)&srvaddr,sizeof(struct sockaddr)) == -1) 	{ 		printf ("connect error\n"); 		close(sockfd); 		exit(1); 	} 	 	 	/*读取用户命令字，case 用户注册*/ 	if (strcmp("register",argv[1]) == 0) 	{ 		printf ("please input username:"); 		scanf ("%s",name); 		printf ("please input userpassword:"); 		scanf ("%s",password); 		 		bzero(buf, sizeof(buf)); 		sprintf (buf,"%s%s%s%s%s",argv[1]," ",name," ",password); 		 		printf ("%s\n",buf); 		 		write(sockfd,buf,strlen(buf)); 		 		if((nbytes = read(sockfd,buf,MAXDATASIZE)) == -1) 		{ 			printf ("read error\n"); 			close(sockfd); 			exit(1); 		} 		buf[nbytes] = '\0'; 		printf ("server response: %s\n", buf); 		 	} 	 	/*读取用户命令字——用户登录*/ 	else if (strcmp(argv[1],"login") ==0) 	{ 		printf ("please input your name:"); 		scanf ("%s",name); 		printf ("please input your password:"); 		scanf ("%s",password); 		 		bzero(buf,sizeof(buf)); 		sprintf (buf,"%s%s%s%s%s",argv[1]," ",name," ",password); 		 		write(sockfd,buf,sizeof(buf)); 		 		 		if((nbytes = read(sockfd,buf,MAXDATASIZE)) == -1) 		{ 			printf ("read error\n"); 			close(sockfd); 			exit(1); 		} 		buf[nbytes] = '\0'; 		//printf ("%d\n",nbytes); 		printf ("server response: %s\n", buf); 		 		nbytes = read(sockfd,buf,MAXDATASIZE);	 		 		//这里创建子进程保证用户在登录状态(没有任何功能选择)时可以收到其他用户的消息，注:若此时收到消息要先输入chat 朋友名,再进行聊天 		if (!fork()) 		{ 			bzero(buf,sizeof(buf)); 			nbytes = read(sockfd,buf,MAXDATASIZE); 			 			if(nbytes == -1) 			{ 				printf ("read error\n");		 				exit(1); 			} 			buf[nbytes] = '\0'; 			//printf ("%d\n",nbytes); 			printf ("%s\n",buf); 			strcpy(bufp,buf); 			p = strtok(buf," "); 			p1 = strtok(NULL," "); 			p2 = strtok(NULL," "); 			if (strcmp(p,"chat") == 0) 			{ 				printf ("\n%s:%s\n\n",p1,p2); 			} 			exit(0); 			 				 		} 		printf ("please input your choose:\n"); 		printf ("********************************\n"); 		printf ("chat	logout	search	cancel\n"); 		printf ("********************************\n"); 		 		for(;;) 		{ 			scanf ("%s",s1); 			 			if (strcmp(s1,"chat") == 0) 			{ 					 					printf ("please choose your friend:"); 					scanf ("%s",name); 					 					while(1) 					{ 						if (!fork()) 						{ 							for(;;) 							{ 								//子进程用于接收消息，父进程发送消息 								bzero(buf,sizeof(buf)); 								if((nbytes = read(sockfd,buf,MAXDATASIZE)) == -1) 								{ 								 									printf ("read error\n");		 									exit(1); 								} 								 								strcpy(bufp,buf); 								p = strtok(buf," "); 								p1 = strtok(NULL," "); 								p2 = strtok(NULL," "); 								if (strcmp(p,"chat") == 0) 								{ 									printf ("\n%s:%s\n\n",p1,p2); 							 								} 									 							} 							exit(0); 			 						} 						//printf ("please input content:"); 						bzero(mes,sizeof(mes)); 						scanf("%s",str); 						printf ("\n"); 						 						bzero(buf,sizeof(buf)); 						 						sprintf (buf,"%s%s%s%s%s",s1," ",name," ",str); 						write(sockfd,buf,sizeof(buf));	 				 					} 			} 		} 	}  	close(sockfd); 	 	return 0; }   引用 3 楼 xingat110 的回复:客户端呢？

user: user-3
content: 客户端呢？

user: user-0
content: 服务器一直都可以收到这两个客户端发送的消息，这说明他们一直处于连接状态的吧。。  引用 1 楼 user-4 的回复:长链接的话，加一个心跳机制吧！ 保证socket套接字一直是有效的！

user: user-4
content: 长链接的话，加一个心跳机制吧！ 保证socket套接字一直是有效的！