linux下socket编程改进版
来源:互联网 发布:win10平板系统优化 编辑:程序博客网 时间:2024/05/07 22:36
通过在bbs提问,增加一个标志位,解决了线程ID不能重复,灰常感谢。
功能还是一样的,服务器接收消息然后打印,加了些服务器发送的确认消息。
注意点:开始客户端的recv函数阻塞住导致我后面无法发送,后来学习到要用非阻塞模式。
下面是代码,写得有点乱。
服务器端:
//server.c#include<stdio.h>#include<stdlib.h>#include<string.h>#include<sys/socket.h>#include<sys/types.h>#include<error.h>#include<errno.h>#include<arpa/inet.h>#include<pthread.h>#include<time.h>#define MAX_LEN 100#define PORT_NUM 4321#define EXIT_FAIL_NUM 1#define MAX_NUM 2void trans(void *p);struct trans_data{int fd;char buff[MAX_LEN];struct sockaddr_in info;}p[MAX_NUM];struct myTherad{ pthread_t tid; int flag;}myThread[MAX_NUM];int main(){int sockfd,confd,len,err,i=0; for(i=0;i<MAX_NUM;i++){ memset(&myThread[i].flag,0,sizeof(int)); printf("thread[%d] flag %d\n",i,myThread[i].flag); }struct sockaddr_in ser,cli;if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0){perror("socket");exit(EXIT_FAIL_NUM);}printf("scoket_fd = %d\n",sockfd);bzero(&ser,sizeof(ser));ser.sin_family = AF_INET;ser.sin_port = htons(PORT_NUM);ser.sin_addr.s_addr = htonl(INADDR_ANY);if(-1 == bind(sockfd,(struct sockaddr *)&ser,sizeof(ser))){perror("bind");exit(EXIT_FAIL_NUM);}if(0 != listen(sockfd,10)){perror("listen");exit(EXIT_FAIL_NUM);}printf("Receive message......\n"); while(1){ len = sizeof(cli); confd = accept(sockfd,(struct sockaddr *)&cli,&len); if(-1 == confd){ perror("accept"); exit(EXIT_FAIL_NUM); } for(i=0;i<MAX_NUM;i++){ if(myThread[i].flag == 0){ p[i].fd = confd; memcpy(&p[i].info,&cli,sizeof(p[i].info)); err = pthread_create(&myThread[i].tid,NULL,(void *)&trans,(void *)&p[i]); if(0 != err){ printf("Can not create thread!\n"); exit(EXIT_FAIL_NUM); } myThread[i].flag = 1; break; } } if(MAX_NUM <= i){ char message[100]; memset(message,0,sizeof(message)); strcpy(message,"服务器没有空余线程,连接即将关闭......"); if( -1 ==send(confd,message,sizeof(message),0)){ perror("send"); exit(EXIT_FAIL_NUM); } } }return 0;}void trans(void *p){ int i; struct tm *t;struct trans_data *ptr;ptr = (struct trans_data *)p; send((*ptr).fd,"服务器线程创建成功...",100,0);while(1){memset((*ptr).buff,0,sizeof((*ptr).buff));int len;if((len = recv((*ptr).fd,(*ptr).buff,sizeof((*ptr).buff),0))<0){ perror("send"); exit(EXIT_FAIL_NUM); } if(len ==0){ for(i=0;i<MAX_NUM;i++){ if(myThread[i].tid == pthread_self()){ myThread[i].flag = 0; break; } } pthread_exit(NULL); } time_t timer; timer = time(NULL); t = localtime(&timer);printf("消息来自:\nIP:%s\t",inet_ntoa((struct in_addr )(*ptr).info.sin_addr));printf("端口号:%d\t",(*ptr).info.sin_port); printf("(%d:%d:%d)\n",(*t).tm_hour,(*t).tm_min,(*t).tm_sec);puts((*ptr).buff);}}
客户端:
//client.c#include<stdio.h>#include<stdlib.h>#include<sys/socket.h>#include<sys/types.h>#include<netinet/in.h>#include<unistd.h>#include<string.h>#include<error.h>#include<errno.h>#include<fcntl.h>#define MAX_LEN 100#define EXIT_FAIL 1#define SERV_IP "127.0.0.1"#define PORT_NUM 4321int main(){int sockfd,confd,len;char buff[MAX_LEN];struct sockaddr_in cli,ser;if((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1){perror("socket");exit(EXIT_FAIL);}printf("socket_fd = %d\n",sockfd);bzero(&ser,sizeof(struct sockaddr_in));ser.sin_family = AF_INET;ser.sin_addr.s_addr = inet_addr(SERV_IP);//"127.0.0.1");ser.sin_port = htons(PORT_NUM);if((confd = connect(sockfd,(struct sockaddr *)&ser,sizeof(struct sockaddr))) == -1){perror("connect");exit(EXIT_FAIL);}printf("连接中......\n"); sleep(2);while(1){ char message[100]; memset(message,0,sizeof(message)); int io_block_var = fcntl(sockfd, F_GETFL, 0); fcntl(sockfd, F_SETFL, io_block_var|O_NONBLOCK); if((len = recv(sockfd,message,sizeof(message),0))>0){ puts(message); if(0 == strcmp(message,"服务器没有空余线程,连接即将关闭......")){ close(sockfd); sleep(3); exit(EXIT_FAIL); } printf("连接成功!!!\n"); } printf("等待发送......\n"); gets(buff);len = send(sockfd,buff,strlen(buff),0);if(len == -1){perror("send");exit(EXIT_FAIL);}memset(buff,0,sizeof(buff));} close(sockfd);return 0;}
运行结果图:
- linux下socket编程改进版
- linux下socket编程再改进版
- LINUX下SOCKET编程
- Linux 下 Socket编程
- Linux下Socket编程
- Linux下Socket编程
- linux下socket编程
- Linux下Socket编程
- Linux下Socket编程
- Linux下Socket编程
- Linux下Socket编程
- Linux下Socket编程
- Linux下Socket编程
- Linux下Socket编程
- Linux下Socket编程
- Linux下Socket编程
- Linux下Socket编程
- Linux下Socket编程
- iPhone UITextField 属性
- 大型的支付系统如何对账、风控
- c语言实现cd的程序(还不能cd进入其他盘)
- 版权声明
- Visual Studio快速开发以及Visual Studio 2010新功能介绍
- linux下socket编程改进版
- 包(pl/sql)
- 大水题Q2002
- 子序列个数
- OpenSSL命令---asn1parse
- python--Tkinter教程之Canvas篇(3)
- 不使用LPCTSTR类型转换
- Mutilated ladies
- POJ2774--Long Long Message