当前位置: 技术问答>linux和unix
Stock通信异常终止的问题
来源: 互联网 发布时间:2015-10-14
本文导语: 我写了一个服务器和客户端通信的程序,每当有一个客户端请求来时,服务器就新建一个线程来处理这个请求,直到客户发来一个表示请求结束的字符串时,才结束这个线程,现在有一个问题:在运行客户端的终端上直接按Ctr...
我写了一个服务器和客户端通信的程序,每当有一个客户端请求来时,服务器就新建一个线程来处理这个请求,直到客户发来一个表示请求结束的字符串时,才结束这个线程,现在有一个问题:在运行客户端的终端上直接按Ctrl+C来结束客户端程序时,服务器也终止了,这是怎么回事?
代码如下:
service.c:
=======
#include "stdio.h"
#include "stdlib.h"
#include "errno.h"
#include "string.h"
#include "sys/types.h"
#include "netinet/in.h"
#include "sys/socket.h"
#include "sys/wait.h"
#include "pthread.h"
#define MYPORT 3490
#define BACKLOG 10
#define MAXDATASIZE 100
void * funThread(void * pStockID)
{
int tt = 1;
int numbytes;
char buf[MAXDATASIZE];
char bufSend[MAXDATASIZE];
long * p = (long *) pStockID;
long lnStockID = *p;
while(tt)
{
if ((numbytes=recv(lnStockID, buf, MAXDATASIZE, 0)) == -1)
{
//perror("recv");
printf("n**recv error**n");
break;
}
buf[numbytes] = '';
printf("n%d : %sn",lnStockID,buf);
if (strcmp(buf,"||Q||") == 0)
{
tt = 0;
break;
}
sprintf(bufSend,"%ld : hello %s!",lnStockID,buf);
if (send(lnStockID, bufSend, strlen(bufSend), 0) == -1)
{
//perror("send");
printf("n**Send error**n");
}
}
printf("n%d closedn",lnStockID);
close(lnStockID);
return (void * ) p;
}
int main()
{
int sockfd,new_fd;
int numbytes;
char buf[MAXDATASIZE];
char bufSend[MAXDATASIZE];
struct sockaddr_in my_addr;
struct sockaddr_in their_addr;
int sin_size;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket"); exit(1);
}
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(MYPORT);
my_addr.sin_addr.s_addr = INADDR_ANY;
bzero(&(my_addr.sin_zero),8);
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1)
{
perror("bind"); exit(1);
}
if (listen(sockfd, BACKLOG) == -1)
{
perror("listen"); exit(1);
}
int nWait = 1;
int ret = 0;
pthread_t id;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
while(1)
{
sin_size = sizeof(struct sockaddr_in);
if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1)
{
perror("accept"); continue;
}
//printf("server: got connection from %s ,fd = %ld", inet_ntoa(their_addr.sin_addr),new_fd);
ret=pthread_create(&id,&attr,(void *)funThread,(void *) &new_fd);
if(ret!=0)
{
printf ("Create pthread error!n");
exit (1);
}
printf("create process ID is %ldn",id);
//close(new_fd);
}
printf("main :C");
//waitpid(-1,NULL,WNOHANG);
close(sockfd);
}
=======
client.c
==========
#include "stdio.h"
#include "stdlib.h"
#include "errno.h"
#include "string.h"
#include "netdb.h"
#include "sys/types.h"
#include "netinet/in.h"
#include "sys/socket.h"
#define PORT 3490
#define MAXDATASIZE 100
int main(int argc, char *argv[])
{
int sockfd, numbytes;
char buf[MAXDATASIZE];
char bufSend[MAXDATASIZE];
struct hostent *he;
struct sockaddr_in their_addr;
if (argc != 2)
{
fprintf(stderr,"usage: client hostname ");
exit(1);
}
if((he=gethostbyname(argv[1]))==NULL)
{
herror("gethostbyname");
exit(1);
}
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket");
exit(1);
}
their_addr.sin_family=AF_INET;
their_addr.sin_port=htons(PORT);
their_addr.sin_addr = *((struct in_addr *)he->h_addr);
bzero(&(their_addr.sin_zero),8);
printf("client is start");
if (connect(sockfd, (struct sockaddr *)&their_addr,sizeof(struct sockaddr)) == -1)
{
perror("connect");
exit(1);
}
int tt = 1;
char chIn;
long nProcessID = (long)getpid();
char strId[MAXDATASIZE];
sprintf(strId,"%d",nProcessID);
while(tt)
{
buf[0] = '';
scanf("%s",buf);
sprintf(bufSend,"%s",buf);
//if (send(sockfd, "kk LL PP",10, 0) == -1)
if (send(sockfd,buf,strlen(buf),0) == -1)
{
perror("send");
}
if(strcmp(buf,"||Q||") == 0)
{
tt = 0;
printf("nclosed: %s",bufSend);
break;
}
if ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) == -1)
{
perror("recv");
break;
}
buf[numbytes] = '';
printf("nGeted: %s",buf);
}
close(sockfd);
return 0;
}
==========
先在一个终端上运行服务器程序,在另一个终端上运行客户程序,输入字符串发给服务器,服务器在收到的字符串前面加上"hello",后发回来,客户端输入||Q||后退出,服务器就终止这个处理线程
代码如下:
service.c:
=======
#include "stdio.h"
#include "stdlib.h"
#include "errno.h"
#include "string.h"
#include "sys/types.h"
#include "netinet/in.h"
#include "sys/socket.h"
#include "sys/wait.h"
#include "pthread.h"
#define MYPORT 3490
#define BACKLOG 10
#define MAXDATASIZE 100
void * funThread(void * pStockID)
{
int tt = 1;
int numbytes;
char buf[MAXDATASIZE];
char bufSend[MAXDATASIZE];
long * p = (long *) pStockID;
long lnStockID = *p;
while(tt)
{
if ((numbytes=recv(lnStockID, buf, MAXDATASIZE, 0)) == -1)
{
//perror("recv");
printf("n**recv error**n");
break;
}
buf[numbytes] = '';
printf("n%d : %sn",lnStockID,buf);
if (strcmp(buf,"||Q||") == 0)
{
tt = 0;
break;
}
sprintf(bufSend,"%ld : hello %s!",lnStockID,buf);
if (send(lnStockID, bufSend, strlen(bufSend), 0) == -1)
{
//perror("send");
printf("n**Send error**n");
}
}
printf("n%d closedn",lnStockID);
close(lnStockID);
return (void * ) p;
}
int main()
{
int sockfd,new_fd;
int numbytes;
char buf[MAXDATASIZE];
char bufSend[MAXDATASIZE];
struct sockaddr_in my_addr;
struct sockaddr_in their_addr;
int sin_size;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket"); exit(1);
}
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(MYPORT);
my_addr.sin_addr.s_addr = INADDR_ANY;
bzero(&(my_addr.sin_zero),8);
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1)
{
perror("bind"); exit(1);
}
if (listen(sockfd, BACKLOG) == -1)
{
perror("listen"); exit(1);
}
int nWait = 1;
int ret = 0;
pthread_t id;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
while(1)
{
sin_size = sizeof(struct sockaddr_in);
if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1)
{
perror("accept"); continue;
}
//printf("server: got connection from %s ,fd = %ld", inet_ntoa(their_addr.sin_addr),new_fd);
ret=pthread_create(&id,&attr,(void *)funThread,(void *) &new_fd);
if(ret!=0)
{
printf ("Create pthread error!n");
exit (1);
}
printf("create process ID is %ldn",id);
//close(new_fd);
}
printf("main :C");
//waitpid(-1,NULL,WNOHANG);
close(sockfd);
}
=======
client.c
==========
#include "stdio.h"
#include "stdlib.h"
#include "errno.h"
#include "string.h"
#include "netdb.h"
#include "sys/types.h"
#include "netinet/in.h"
#include "sys/socket.h"
#define PORT 3490
#define MAXDATASIZE 100
int main(int argc, char *argv[])
{
int sockfd, numbytes;
char buf[MAXDATASIZE];
char bufSend[MAXDATASIZE];
struct hostent *he;
struct sockaddr_in their_addr;
if (argc != 2)
{
fprintf(stderr,"usage: client hostname ");
exit(1);
}
if((he=gethostbyname(argv[1]))==NULL)
{
herror("gethostbyname");
exit(1);
}
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket");
exit(1);
}
their_addr.sin_family=AF_INET;
their_addr.sin_port=htons(PORT);
their_addr.sin_addr = *((struct in_addr *)he->h_addr);
bzero(&(their_addr.sin_zero),8);
printf("client is start");
if (connect(sockfd, (struct sockaddr *)&their_addr,sizeof(struct sockaddr)) == -1)
{
perror("connect");
exit(1);
}
int tt = 1;
char chIn;
long nProcessID = (long)getpid();
char strId[MAXDATASIZE];
sprintf(strId,"%d",nProcessID);
while(tt)
{
buf[0] = '';
scanf("%s",buf);
sprintf(bufSend,"%s",buf);
//if (send(sockfd, "kk LL PP",10, 0) == -1)
if (send(sockfd,buf,strlen(buf),0) == -1)
{
perror("send");
}
if(strcmp(buf,"||Q||") == 0)
{
tt = 0;
printf("nclosed: %s",bufSend);
break;
}
if ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) == -1)
{
perror("recv");
break;
}
buf[numbytes] = '';
printf("nGeted: %s",buf);
}
close(sockfd);
return 0;
}
==========
先在一个终端上运行服务器程序,在另一个终端上运行客户程序,输入字符串发给服务器,服务器在收到的字符串前面加上"hello",后发回来,客户端输入||Q||后退出,服务器就终止这个处理线程
|
我也不想看代码,但我可以告诉你当对方的socket关闭的时候,会发送一个连接关闭的报文,本地可以检测到,与此本地进程如果继续在这个socket上读会出错
|
我不想看代码,我只知道要找出原因很简单,直接用GDB/KDBG跟踪你服务器代码退出阶段的代码就找到原因了,干嘛费时间在这里看。
|
有生成.core文件吗?
|
recv返回为0时要处理,关闭socket退出线程