TCP回射1-----线程

    xiaoxiao2025-09-07  635

    实现数据的回射功能,服务器端接收到客户端发送来的数据时会将同样数据发送回去,客户端之间没有数据通信

    服务器端代码

    #include <string.h> #include <stdio.h> #include <stdlib.h> #include <netinet/in.h> #include <sys/types.h> #include <pthread.h> #define LISTEN_NUM 10 //最大允许连接数 /** 回射函数的处理,当收到客户单发送来的数据时将同样数据发送回去 **/ void* process(void *arg) { char buf[1024] = {0}; int conn_fd = *(int*)arg; int ret; while((ret = read(conn_fd, buf, sizeof(buf))) > 0) { if(ret > 0) { write(conn_fd, buf, strlen(buf)); memset(buf, 0, sizeof(buf)); } else if(ret == 0) { printf("the clint has closed\n"); conn_fd = 0; close(conn_fd); return NULL; } else { printf("error ret = %d", ret); return NULL; } } } /** 启动服务器并进行侦听,基本套路 **/ int serve_tcp_start(const int port) { int sockID; sockID = socket(AF_INET, SOCK_STREAM, 0); if(sockID < 0) { perror("socket"); return -1; } struct sockaddr_in serName; memset(&serName, 0, sizeof(serName)); serName.sin_port = htons(port); serName.sin_family = AF_INET; serName.sin_addr.s_addr = htonl(INADDR_ANY); if(bind(sockID, (struct sockaddr*)&serName, sizeof(serName)) < 0) { perror("bind"); return -1; } if(listen(sockID, LISTEN_NUM) < 0) { perror("listen"); return -1; } return sockID; } /** 判断哪个套接口可用 **/ int get_conn_fd(int *fd) { int i; for(i=0; i<LISTEN_NUM; i++) { if(*(fd+i) == 0) return i; } return -1; } int main() { /*declare variables*/ int sock_fd; int port = 8086; int pos = 0; int conn_fd[LISTEN_NUM] = {0}; pthread_t pid[LISTEN_NUM]; sock_fd = serve_tcp_start(port); //启动服务器 if(sock_fd < 0) { perror("serve_tct_start\n"); return 0; } int tempConn; while(1) { tempConn = accept(sock_fd, NULL, NULL); //accept一直保持一个阻塞状态,当一个连接请求到达,会分配一个用于通信的描述符 pos = get_conn_fd(conn_fd); //找出一个可用的通信描述符 if(pos == -1) { printf("no varibale socket for connect\n"); //如果没有可用就把连接丢弃了 } else { conn_fd[pos] = tempConn; pthread_create(&pid[pos], NULL, process, (void*)&conn_fd[pos]); //分配一个线程用于处理数据 } } return 0; }

    客户端代码

    #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> /** 获取客户端的socket int port, char *ip 端口和ip地址 **/ int getClintSocket(int port, char *ip) { int sockID; sockID = socket(AF_INET, SOCK_STREAM, 0); if(sockID == -1) { perror("socket"); return 0; } struct sockaddr_in clint; memset(&clint, 0, sizeof(clint)); clint.sin_port = htons(port); clint.sin_family = AF_INET; inet_pton(AF_INET, ip, &clint.sin_addr); int flag = connect(sockID, (struct sockaddr*)&clint, sizeof(clint)); if(flag < 0) return -1; return sockID; } int main() { int port = 8086; char *ip = "192.168.179.128"; int sock_fd = getClintSocket(port, ip); //得到套接字 if(sock_fd < 0) { perror("connect"); return 0; } char buf[1024] = {0}; while(fgets(buf, sizeof(buf), stdin) != NULL) { //用fgets函数获取控制台的输入 if(strcmp(buf, "exit\n") == 0) { //判断得到的字符是否是exit,是就断开连接,fgets会记录回车'\n' printf("close the socket and quit\n"); break; } else { write(sock_fd, buf, strlen(buf)-1); //向服务器端写数据,同时清空buf memset(buf, 0, sizeof(buf)); read(sock_fd, buf, sizeof(buf)); //从服务器端得到数据,打印到控制台 printf("recv the message:%s\n", buf); } } printf("socket is close\n"); close(sock_fd); return 0; }结果

    转载请注明原文地址: https://ju.6miu.com/read-1302411.html
    最新回复(0)