为什么一个线程结束了整个程序都结束了
本帖最后由 butterinsect 于 2011-05-09 22:22 编辑
下面是一个多线程长连接的服务器,客户端发送数据过来,服务器接受数据,然后返回大写的数据
server.c
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <unistd.h>
- #include <errno.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/wait.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <pthread.h>
- void handleData(int *new_fd);
- #define THREAD_NUMBER 5
- pthread_t pt[THREAD_NUMBER];
- int main(int argc, char **argv)
- {
- struct sockaddr_in server_addr;
- struct sockaddr_in client_addr;
- int sockfd, new_fd[THREAD_NUMBER];
- int *arg;
- int portnumber, sin_size;
- if(argc!=2)
- {
- fprintf(stderr, "the argc is not enough!\n");
- }
- if(atoi(argv[1])<0)
- {
- fprintf(stderr, "port is not right!\n");
- exit(1);
- }
- portnumber = atoi(argv[1]);
- if((sockfd=socket(AF_INET, SOCK_STREAM, 0))==-1)
- {
- fprintf(stderr, "the server socket init error:%s\n", strerror(errno));
- exit(0);
- }
- //端口重用
- int on = 1;
- setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
- //初始化server_addr
- bzero(&server_addr, sizeof(struct sockaddr_in));
- server_addr.sin_family = AF_INET;
- server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
- server_addr.sin_port = htons(portnumber);
- //绑定
- if(bind(sockfd, (struct sockaddr*)(&server_addr), sizeof(struct sockaddr))==-1)
- {
- fprintf(stderr, "the server bind error:%s\n", strerror(errno));
- exit(1);
- }
- if(listen(sockfd, 5)==-1)
- {
- fprintf(stderr, "the server listen error:%s\n", strerror(errno));
- exit(1);
- }
- int k = 0;
- while(1)
- {
- sin_size = sizeof(struct sockaddr_in);
- if((new_fd[k]=accept(sockfd, (struct sockaddr*)(&client_addr),&sin_size))==-1)
- {
- fprintf(stderr, "the server accept error:%s\n", strerror(errno));
- continue;
- }
- printf("new connection is coming...\n");
- if(pthread_create(&pt[k], &attr, (void *)handleData, (void *)&new_fd[k])!=0)
- {
- printf("new thread error!\n");
- }
- k++;
- }
- int i;
- for(i=0; i<THREAD_NUMBER; i++)
- {
- int ret_val = pthread_join(pt[i], NULL);
- if(ret_val!=0)
- {
- printf("pthread_join error!\n");
- exit(1);
- }
- }
- close(sockfd);
- return 0;
- }
- void handleData(int *new_fd)
- {
- char *msg;
- while(1)
- {
- msg = (char*)malloc(sizeof(char)*1024);
- memset(msg, 0, 1024);
- if(read(*new_fd, msg, 1024)==-1)
- {
- fprintf(stderr, "the server read error\n");
- // exit(1);
- continue;
- }
- int len = strlen(msg);
- int i;
- for(i=0; i<len; i++)
- {
- if(msg[i]>='a'&&msg[i]<='z')
- msg[i]=msg[i]-32;
- }
- msg[len]='\0';
- if(write(*new_fd, msg, 1024)==-1)
- {
- fprintf(stderr, "the server write error\n");
- exit(1);
- }
- }
- //free(msg);
- pthread_exit(msg);
- }
复制代码client.c
- /************************************************
- *author:butterinsect
- *email:yyt5116@163.com
- *school:cug
- *blog:www://hi.baidu.com/butterinsect
- *接受键盘输入,然后把信息发送到服务器
- * ************************************************/
- #include <stdlib.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <errno.h>
- #include <string.h>
- #include <sys/socket.h>
- #include <sys/types.h>
- #include <netinet/in.h>
- #include <netdb.h>
- int main(int argc, char** argv)
- {
- int sockfd;
- struct sockaddr_in server_addr;
- struct hostent *host;
- int portnumber, nbytes;
- char msg[1024];
- if(argc!=3)
- {
- fprintf(stderr, "the argv is not enough 3!\n");
- exit(1);
- }
- if(inet_aton(argv[1], &server_addr)!=0)
- host = gethostbyaddr((char *)&server_addr, 4, AF_INET);
- else
- host = gethostbyname(argv[1]);
- if((portnumber=atoi(argv[2]))<0)
- {
- fprintf(stderr, "the port of client is error\n");
- exit(1);
- }
- if((sockfd = socket(AF_INET, SOCK_STREAM, 0))==-1)
- {
- fprintf(stderr, "client socket init error:%s\n", strerror(errno));
- exit(1);
- }
- bzero(&server_addr, sizeof(server_addr));
- server_addr.sin_family = AF_INET;
- server_addr.sin_port = htons(portnumber);
- server_addr.sin_addr = *((struct in_addr*)host->h_addr);
- if(connect(sockfd, (struct sockaddr*)(&server_addr), sizeof(struct sockaddr))==-1)
- {
- fprintf(stderr, "the clinet connect error:%s\n", strerror(errno));
- exit(1);
- }
- while(1)
- {
- gets(msg);
- int len = strlen(msg);
- msg[len]='\0';
- if(write(sockfd, msg, 1024)==-1)
- {
- fprintf(stderr, "the client write error:%s\n", strerror(errno));
- exit(1);
- }
- memset(msg, '0', 1024);
- if((nbytes=read(sockfd, msg, 1024))==-1)
- {
- fprintf(stderr, "the client read error:%s\n", strerror(errno));
- exit(1);
- }
- msg[nbytes]='\0';
- printf("after tacked:%s\n", msg);
- }
- close(sockfd);
- return 0;
- }
复制代码然后运行server
./server 8080
然后运行客户端1
yyt@yyt:~/workspace/apue/tcp/tcpmp$ ./client localhost 8080
hello
after tacked:HELLO
abdc
after tacked:ABDC
然后运行客户端2
yyt@yyt:~/workspace/apue/tcp/tcpmp$ ./client localhost 8080
good
after tacked:GOOD
simida
after tacked:SIMIDA
当ctrl+c结束客户端1时候,服务器也退出了,why!!!!
怎么设置服务器线程的属性,一个线程结束而整个程序不结束??
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
![扫码二维码加入Web技术交流群](/public/img/jiaqun_03.jpg)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
server线程不要用exit()
本帖最后由 jimmyixy 于 2011-05-10 10:35 编辑
客户端ctl c 是向服务器发送了SIGPIPE信号,服务器端觉得客户端写异常直接退出
复制代码这样是可以的
当所有客户端都断开时server端也不会退出,看你的需求了
回复 3# jimmyixy
多谢,就是这个问题