第一句子网 - 唯美句子、句子迷、好句子大全
第一句子网 > TCP服务器连接多客户端(C语言实现)

TCP服务器连接多客户端(C语言实现)

时间:2024-05-02 05:53:29

相关推荐

TCP服务器连接多客户端(C语言实现)

目录

设计思路:

逻辑设计:

代码实现:

运行结果:

设计思路:

在服务端客户端T一对一TCP的基础上增加几条通信即可,要求各个连接可同时进行通信因此使用多线程。主线程在listen实现后,使用一个 for 循环一直循环等待客户端的连接请求,将每次连接标记(sockFd)保存作为开启检测(检测条件可自行修改,我这个检测判断貌似也没起啥作用 也先不改了(▼ヘ▼#),可以采用远端 IP 检查或者 IP+port 等方式来作为检测条件)。每次连接都会开启一个线程用于和客户端的通信(也是使用 for 循环进行数据的接收、处理、发送),数据接收使用阻塞等待。通信的具体实现,在开发板上部署运行下方的服务器端程序,客户端则在PC端网络调试助手开启多个port与服务器完成多个连接进行通信。

逻辑设计:

TCP服务器端逻辑设计

代码实现:

#include <stdio.h>#include <sys/resource.h>#include <unistd.h>#include <pthread.h>#include <string.h>#include <sys/socket.h>/*********************************************************************************************************宏定义*********************************************************************************************************/#define __TCP_ECHO_TYPE_CLIENT1 /* 客户端模式 */#define __TCP_ECHO_TYPE_SERVER2 /* 服务器模式 */#define __TCP_ECHO_TYPE (__TCP_ECHO_TYPE_SERVER) /* 当前模式选择 */#define __TCP_ECHO_IP_CLIENT "192.168.1.16" /* 客户端 IP 地址*/#define __TCP_ECHO_IP_SERVER "192.168.1.17" /* 服务器 IP 地址*/#define __TCP_ECHO_PORT_CLIENT8100 /* 客户端端口号 */#define __TCP_ECHO_PORT_SERVER8101 /* 服务器端口号 */#define __TCP_ECHO_BUFF_SIZE_CLIENT257 /* 客户端接收缓冲区大小 */#define __TCP_ECHO_BUFF_SIZE_SERVER257 /* 服务器接收缓冲区大小 *//*********************************************************************************************************** 函数名称: 线程函数** 功能描述: 为每个tcp连接开启一个线程 用于数据的接收、处理和发送** 输入 :** 输出 :** 全局变量:** 调用模块:*********************************************************************************************************/void * tcpThread(void * arg){int sockFd = *(int *)arg;char cRecvbuffer[__TCP_ECHO_BUFF_SIZE_SERVER]={0};ssize_t sstrRecv = 0;for(;;){memset(cRecvbuffer, 0, __TCP_ECHO_BUFF_SIZE_SERVER);sstrRecv = read(sockFd, (void *)cRecvbuffer, __TCP_ECHO_BUFF_SIZE_SERVER);fprintf(stdout,"TCP server recive: %s\n",cRecvbuffer);if(sstrRecv <= 0){if((ETIMEDOUT != 0) && (EWOULDBLOCK != 0)){close(sockFd);fprintf(stderr,"TCP server bind error!\n");return (void *)(-1);}continue;}write(sockFd, (const void *)cRecvbuffer, sstrRecv);}}/*********************************************************************************************************** 函数名称: main** 功能描述: 主函数** 输入 : argc,argv** 输出 : ERROR** 全局变量:** 调用模块:*********************************************************************************************************/int main (int argc, char *argv[]){int sockFdConn[5];/* 各客户端的套接口描述符 */int i, connTemp; /* 临时套接口描述符 */int connNum;/* 标记当前连接编号 */int sockFd = -1; /* 套接字描述符 */int iRet = -1; /* 返回值判断 */int connMax = -1; /* 连接的客户端总数 */pthread_t tid[5]; /* 线程句柄 */struct sockaddr_in sockaddrinRemote;struct sockaddr_in sockaddrinLocal;socklen_t size_sin = sizeof(struct sockaddr_in);sockFd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); /* 创建本地socket连接 */if(sockFd < 0){fprintf(stderr,"tcp server socket creat error!\n");return -1;}fprintf(stdout,"tcp server socket creat success!\n");/** 初始化本地地址结构*/memset(sockFdConn, -1, sizeof(sockFdConn));// memset(sockaddrinLocal, 0 ,sizeof(sockaddrinLocal));sockaddrinLocal.sin_len = sizeof(struct sockaddr_in);sockaddrinLocal.sin_family = AF_INET;sockaddrinLocal.sin_addr.s_addr = INADDR_ANY;sockaddrinLocal.sin_port = htons(__TCP_ECHO_PORT_SERVER);/** 增加地址复用*/iRet = setsockopt(sockFd, SOL_SOCKET, SO_REUSEADDR, &iRet, sizeof(int));if(iRet < 0){fprintf(stderr,"TCP reuseADDR error!\n");return -1;}/** 绑定本地地址与端口*/iRet = bind(sockFd, (struct sockaddr *)&sockaddrinLocal, sizeof(sockaddrinLocal));if(iRet < 0){fprintf(stderr,"TCP server bind error!\n");return -1;}fprintf(stdout,"TCP server bind success!\n");listen(sockFd, 5);fprintf(stdout,"TCP server bind listening ...\n");for(;;){// bzero(&sockaddrinRemote, sizeof(sockaddrinRemote));connTemp = accept(sockFd, (struct sockaddr *)&sockaddrinRemote, &size_sin);/* 同客户端创建连接 */fprintf(stdout,"RemoteAddr:%s, RemotePort:%hu\n", inet_ntoa(sockaddrinRemote.sin_addr),ntohs(sockaddrinRemote.sin_port));if(connTemp < 0){close(sockFd);fprintf(stderr,"TCP server accept error!\n");return -1;}/** 检查当前连接是否存在(检查Fd不太合适,可自行修改)*/for(i=0; i<=connMax; i++){if(connTemp == sockFdConn[i]){connNum =i;break;}}if(i > connMax){connNum = ++connMax;sockFdConn[connNum]=connTemp;pthread_create(&tid[connNum], NULL, tcpThread, (void*)&sockFdConn[connNum]);}// fprintf(stdout,"sockFdConn: %d\n",sockFdConn[cnt]);}close(sockFd);return 0;}/*********************************************************************************************************END*********************************************************************************************************/

运行结果:

多连接开启

程序进行中

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。