Linux C: 基于C/S的多线程网络编程 (服务器充当一个客户端的两点传输)

来源:互联网 发布:北大发展研究院知乎 编辑:程序博客网 时间:2024/06/05 17:58

服务器端代码:

#include<stdio.h>#include<stdlib.h>#include<string.h>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<arpa/inet.h>#include<unistd.h>#include<signal.h>#include<pthread.h>int tcp_init(const char* ip, int port)  //用于初始化{int sfd = socket(AF_INET, SOCK_STREAM, 0); //首先建立一个Socket,向系统申请if(sfd == -1){perror("Socket error\n");exit(1);}struct sockaddr_in serveraddr;memset( &serveraddr, 0, sizeof(struct sockaddr) ); serveraddr.sin_family = AF_INET;serveraddr.sin_port = htons(port); //将主机的无符号短整形数转换成网络字节顺序。hostshort:主机字节顺序表达的16位数serveraddr.sin_addr.s_addr = inet_addr(ip); //或者INADDR_ANY//将新的socket和制定的ip、port绑定if(bind(sfd, (struct sockaddr*)&serveraddr, sizeof(struct sockaddr)) == -1){perror("Bind Error");close(sfd);exit(-1);}if(listen(sfd, 10) == -1)  //监听它 最大连接数为10{perror("Listen error"); close(sfd);exit(-1);}return sfd;}int tcp_accept(int sfd){struct sockaddr_in clientaddr;memset(&clientaddr, 0, sizeof(struct sockaddr) );    int addrlen = sizeof(struct sockaddr);int new_fd = accept(sfd, (struct sockaddr*)&clientaddr, &addrlen);//sfd接受客户端的连接,创建新的socket为new_fd, 将请求连接的客户端IP//port保存在结构体clientaddr中if(new_fd == -1){perror("accept error");close(sfd);exit(-1);}printf("%s %d success connect...\n", inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port));//inet_ntoa:函数功能:将网络地址转换成“.”点隔的字符串格式。return new_fd;}void signalhandler(void){sigset_t sigSet;sigemptyset(&sigSet);sigaddset(&sigSet,SIGINT);sigaddset(&sigSet,SIGQUIT);sigprocmask(SIG_BLOCK,&sigSet,NULL); }typedef struct{int sfd;int cfd;}tcp_info;void* pthread_send(void *arg){tcp_info *temp;temp = ( tcp_info *)arg;char buf[128];while(1){memset(buf, 0, sizeof(buf));scanf("%s",buf);if(send(temp->cfd, buf, 128, 0) == -1){perror("send");close(temp->cfd);close(temp->sfd);exit(-1);}sleep(1);}}void* pthread_recv(void *arg){memset(buf, 0, sizeof(buf));tcp_info *temp;temp = ( tcp_info *)arg;char buf[128] = {0};while(1){if(recv(temp->cfd, buf, sizeof(buf), 0 ) == -1){perror("recv");close(temp->cfd);close(temp->sfd);exit(-1);}printf("\n");puts(buf);}}int main(int argc,char **argv){int ret_send;int ret_recv;pthread_t id1;pthread_t id2;if(argc < 3){printf("usage:./servertcp ip port \n");exit(-1);}signalhandler();int sfd = tcp_init(argv[1], atoi(argv[2]));//atoi:把字符串转化成整形的函数,例如atoi(“123”) = 123//这里也可以这样写: int sfd = tcp_init("192.168.0.164",8888);int cfd = tcp_accept(sfd);tcp_info *info; info = (tcp_info*)malloc(sizeof(tcp_info));info->sfd = sfd;info->cfd = cfd;ret_send = pthread_create(&id1, NULL, pthread_send, (void*)info);ret_recv = pthread_create(&id2, NULL, pthread_recv, (void*)info); pthread_join(id1, NULL);pthread_join(id2, NULL);close(cfd);close(sfd);return 0;}

客户端代码:


#include<stdio.h>#include<stdlib.h>#include<string.h>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<arpa/inet.h>#include<unistd.h>#include<signal.h>#include<pthread.h>int tcp_connect(const char* ip, int port)  //用于客户端的连接{int sfd = socket(AF_INET, SOCK_STREAM, 0); //向系统申请注册新的socketif(sfd == -1){perror("Socket error");exit(-1);}struct sockaddr_in serveraddr;memset(&serveraddr, 0, sizeof(struct sockaddr) );serveraddr.sin_family = AF_INET;serveraddr.sin_port = htons(port);serveraddr.sin_addr.s_addr = inet_addr(ip);//将sfd连接到制定的服务器serveraddrif( connect(sfd,(struct sockaddr*) &serveraddr,sizeof(struct sockaddr) ) == -1 ){perror("Connect error");close(sfd); exit(-1); }return sfd;}void* pthread_send(void *arg){int *temp;temp = (int *)arg; char buf[128];while(1){memset(buf, 0, sizeof(buf));scanf("%s",buf);send(*temp, buf, 512, 0); //向sfd服务端发送数据sleep(1);} }void* pthread_recv(void *arg){int *temp;temp = (int *)arg;char buf[128] = {0};while(1){memset(buf, 0, sizeof(buf));recv(*temp, buf, sizeof(buf), 0); //接收sfd服务端的数据puts(buf);}}int main(int argc,char **argv){    int ret_send;    int ret_recv; pthread_t id1;    pthread_t id2;if(argc < 3){printf("usage:./client ip port\n");exit(-1);}int sfd = tcp_connect(argv[1],atoi(argv[2]));void *a;int *b = &sfd;    ret_send = pthread_create(&id1, NULL, (void*)pthread_send, (void*)b);ret_recv = pthread_create(&id2, NULL, (void*)pthread_recv, (void*)b);pthread_join(id1, NULL);    pthread_join(id2, NULL);close(sfd);return 0;}


0 0
原创粉丝点击