- 论坛徽章:
- 0
|
本帖最后由 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!!!!
怎么设置服务器线程的属性,一个线程结束而整个程序不结束?? |
|