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;}

运行结果图:



原创粉丝点击