socket编程之pthread多线程通信

来源:互联网 发布:蜂窝网络和移动网络 编辑:程序博客网 时间:2024/04/29 13:28


/************************************************************************* *  Copyright (C): 1540999272@qq.com *  Filename:      server.c *  Author:        Lu Zengmeng *  Description:   创建子线程接受客户端数据 *  Creat Time:    2016-07-19 12:08 ************************************************************************/#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <unistd.h> #include <arpa/inet.h> #include <netinet/in.h> #include <strings.h> #include <errno.h> #include <pthread.h> #define PORT            8003#define BACKLOG     10#define BUF_LEN     128void *recv_data(void *fd);int main(int argc, char **argv){        int      sockfd;        int      *conn_fd;        struct   sockaddr_in addr;        if(-1==(sockfd=socket(AF_INET,SOCK_STREAM,0)))        {                perror("socket");                exit(1);        }        addr.sin_family = AF_INET;        addr.sin_port = htons(PORT);        addr.sin_addr.s_addr = htons(INADDR_ANY);        bzero(&(addr.sin_zero),8);        if(-1==(bind(sockfd,(struct sockaddr*)&addr,sizeof(addr))))        {                perror("bind");                exit(1);        }        if(-1==listen(sockfd, BACKLOG))        {                perror("listen");                exit(1);        }        while(1)        {        pthread_t thread;        conn_fd = (int*)malloc(sizeof(int));                if (-1 == (*conn_fd = accept(sockfd, NULL, NULL)))                {                        perror("accept");                    continue;                }        if (0!= pthread_create(&thread,NULL,recv_data,conn_fd))        {            perror("pthread_create");            break;        }        }    shutdown(sockfd,2);    shutdown(*conn_fd,2);    return 0;}void *recv_data(void *fd){        int               conn_fd;        int               recv_len;        unsigned char     recv_buf[BUF_LEN];    conn_fd = *((int*)fd);    for(;;)    {        memset(recv_buf,0,BUF_LEN);            recv_len = recv(conn_fd,recv_buf,BUF_LEN,0);        if(-1==recv_len)        {            perror("recv");            exit(1);        }            recv_buf[recv_len] = '\0';        if(strncmp(recv_buf,"exit",4)==0)        {            printf("%s\n",recv_buf);            break;        }            printf("Receive data:%s\n", recv_buf);    }    free(fd);        close(conn_fd);    pthread_exit(NULL);}

编译服务器时需要链接phtread库

gcc -lpthread server.c -o server



上述代码中pthread_create函数用来创建线程并执行线程函数,函数原型为int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg),第一个参数thread为线程标识符,第二个参数attr是线程属性设置,第三个参数start_routine为线程函数地址,第四个参数arg为传给线程函数的参数。该函数声明在pthread.h头文件中,实现在pthread库。函数成功执行返回0,失败返回-1。

pthread_exit()函数用来结束该线程,相当于进程中的exit()函数。


/************************************************************************* *  Copyright (C): 1540999272@qq.com *  Filename:      server.c *  Author:        Lu Zengmeng *  Description:   客户端程序,向服务器发送数据 *  Creat Time:    2016-07-19 12:08 ************************************************************************/#include <stdio.h>#include <sys/types.h>#include <sys/socket.h>#include <arpa/inet.h>#include <netinet/in.h>#include <strings.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <fcntl.h>#include <sys/stat.h>#include <time.h>#define PORT             8003#define BUF_LEN          100int main(int argc, char *argv[]){        int                    sockfd;        unsigned char          send_buf[BUF_LEN];        unsigned char          send_len;        struct sockaddr_in     serv_addr;    if (argc != 2)    {        printf("Usage: %s ServerIP\n",argv[0]);        exit(1);    }    bzero(&serv_addr,sizeof(serv_addr));    serv_addr.sin_family = AF_INET;    serv_addr.sin_port   = htons(PORT);    if ((inet_pton(AF_INET,argv[1],&serv_addr.sin_addr)) < 0)    {        perror("inet_pton");        exit(1);    }    if (-1 == (sockfd = socket(AF_INET, SOCK_STREAM, 0)))    {        perror("socket");        exit(1);    }    if (-1 == connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)))    {        perror("connect");        exit(1);    }    for(;;)    {        memset(send_buf,0,BUF_LEN);        printf("Input your data:\n");        fgets(send_buf,BUF_LEN,stdin);        fflush(stdin);        if(strncmp(send_buf,"exit",4)==0)         {            if (-1 == (send(sockfd, send_buf, BUF_LEN,0)))                {                    perror("read");                    exit(1);                }            break;        }        if (-1 == (send(sockfd, send_buf, BUF_LEN,0)))            {            perror("read");            exit(1);            }    }    close(sockfd);        return 0;}


int strncmp(const char *s1, const char *s2, size_t n);该函数用来比较字符串s1和s2的前n个字符,相同返回0,s1大于s2返回正值,s1小于s2返回负值。

0 0
原创粉丝点击