TCP回射1-----线程

来源:互联网 发布:python sys.exit 2 编辑:程序博客网 时间:2024/06/05 03:33

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


服务器端代码

#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>/**获取客户端的socketint 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);//向服务器端写数据,同时清空bufmemset(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;}
结果


0 0