基于tcp的一个服务器对应多个客户端的连接

1、服务端

#include <stdlib.h>
#include <sys/types.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <pthread.h>

#include <sys/time.h>
#include <sys/select.h>
#include <errno.h>
#include <signal.h>

void *client_phtread(void *arg)
{
	int nfp , *p, num = 0;
	char buffer[100] = {0};
	ssize_t len=0; 
	p = (int *)arg;
	nfp = *p;
	fd_set  readfds,tmpfds;
	struct timeval timeval;
	int ret=0;
	printf("nfp %d client enter\n",nfp);
	
	FD_ZERO(&readfds);
	FD_SET(nfp,&readfds);
	
	while(1) {
		tmpfds = readfds;
		timeval.tv_sec = 5;
		timeval.tv_usec = 0;
		//sleep(1);
		ret = select(nfp+1,&tmpfds,NULL,NULL,&timeval);
		if(ret < 0) {
			printf("select fail\n");
			break;
		}else if(ret == 0) {
			printf("select %d timeout\n",nfp);
		}else{
			if(FD_ISSET(nfp,&tmpfds)) {
				memset(buffer, 0, 100);
				len = recv(nfp, buffer, sizeof(buffer), 0);
				if(len  == -1) {
					printf("%d recv errno %d:%s\n",nfp,errno,strerror(errno));
					break;
				}else if(len == 0){
					printf("%d recv len %ld\n",nfp,len);
					break;
				}else{
					printf("%d recv len %ld date:%s\n",nfp,len,buffer);
				}
			}				
		}

	}
	printf("nfp %d client end\n",nfp);
	close(nfp);
	pthread_exit(NULL);
	
}
int sfp;
void mainexit(int sig)
{
	printf("sig %d",sig);
	close(sfp);
}
int main()
{
	int nfp;
	struct sockaddr_in s_add,c_add;
	int sin_size;
	unsigned short portnum=9006;
	fd_set  readfds,tmpfds;
	struct timeval timeval;
	int ret=0;
	pthread_t  client_tid;
	
	printf("Hello,welcome to my server !\r\n");
	
	signal(SIGINT, mainexit);
	
	sfp = socket(AF_INET, SOCK_STREAM, 0);
	
	if(-1 == sfp) {
		printf("socket fail ! \r\n");
		return -1;
	}

	printf("socket ok !\r\n");

	bzero(&s_add,sizeof(struct sockaddr_in));
	s_add.sin_family=AF_INET;
	s_add.sin_addr.s_addr=htonl(INADDR_ANY);
	s_add.sin_port=htons(portnum);

	if(-1 == bind(sfp,(struct sockaddr *)(&s_add), sizeof(struct sockaddr))) {
		printf("bind fail !\r\n");
		return -1;
	}

	printf("bind ok !\r\n");

	if(-1 == listen(sfp,5)) {
		printf("listen fail !\r\n");
		return -1;
	}

	printf("listen ok\r\n");

	sin_size = sizeof(struct sockaddr_in);
	
	FD_ZERO(&readfds);
    FD_SET(sfp,&readfds);

	while(1) {
		tmpfds = readfds;
		timeval.tv_sec = 10;
		timeval.tv_usec = 0;
		ret = select(sfp+1,&tmpfds,NULL,NULL,&timeval);
		if( ret < 0) {
			printf("%d select errno %d:%s\n",sfp, errno,strerror(errno));
			break;
        }else if(ret == 0 ) {
			printf("select %d timeout\n",sfp);
		}else{
			if(FD_ISSET(sfp,&tmpfds)) {
				nfp = accept(sfp, (struct sockaddr *)(&c_add), &sin_size);
				if(-1 == nfp) {
					printf("%d accept errno %d:%s\n",sfp, errno,strerror(errno));
					continue;
				}else {
					printf("accept ok!\r\nServer start get connect from ip:%s port:%d\r\n", inet_ntoa(c_add.sin_addr), c_add.sin_port);
					pthread_create(&client_tid, NULL, client_phtread, &nfp);	
				}
			}
		}	
	}
	close(sfp);

	return 0;
}

2、客户端

#include <stdlib.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <errno.h>

int main(int argc, char **argv)
{
	int cfd;
	int recbyte;
	int sin_size;
	char buffer[512] = {0};
	char *str;
	struct sockaddr_in s_add, c_add;
	unsigned short portnum=0 ;
	int len;
	
	printf("Hello,welcome to client!\r\n");

	if(argc != 3) {
		printf("usage: echo ip\n");
		return -1;
	}
	
	portnum = atoi(argv[2]);
	
	cfd = socket(AF_INET, SOCK_STREAM, 0);
	if(-1 == cfd) {
		printf("socket fail ! \r\n");
		return -1;
	}

	printf("socket ok !\r\n");

	bzero(&s_add,sizeof(struct sockaddr_in));
	s_add.sin_family=AF_INET;
	s_add.sin_addr.s_addr= inet_addr(argv[1]);
	s_add.sin_port=htons(portnum);
	
	printf("server = %s ,port : %d\r\n",argv[1],portnum);

	if(-1 == connect(cfd,(struct sockaddr *)(&s_add), sizeof(struct sockaddr))) {
		printf("connect fail !\r\n");
		return -1;
	}

	printf("connect ok !\r\n");

	while(1) {
		sleep(1);
		memset(buffer, 0, sizeof(buffer));
		printf("please enter:");
		if(scanf("%s",buffer)) {
			len = send(cfd,buffer,strlen(buffer),MSG_NOSIGNAL);
			if(len == -1) {
				printf("errno %d:%s\n",errno,strerror(errno));
				break;
			}
		}
	}
	close(cfd);
	return 0;

}

 

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在Qt中,可以使用QTcpSocket和QTcpServer类来实现TCP连接多个客户端。下面是一种实现方法: 首先,创建一个QTcpServer对象来监听客户端连接: ```cpp QTcpServer server; server.listen(QHostAddress::Any, 1234); // 监听本地端口1234 ``` 然后,在有新客户端连接时,使用QTcpServer的newConnection信号槽将其连接一个新的QTcpSocket对象: ```cpp connect(&server, &QTcpServer::newConnection, [=]() { QTcpSocket* socket = server.nextPendingConnection(); // 将socket添加到一个容器中,以便管理多个客户端连接 }); ``` 接下来,可以使用QTcpSocket对象与客户端进行通信。可以在readyRead信号槽中处理接收到的数据,以及在disconnected信号槽中处理客户端断开连接的情况: ```cpp connect(socket, &QTcpSocket::readyRead, [=]() { QByteArray data = socket->readAll(); // 处理接收到的数据 }); connect(socket, &QTcpSocket::disconnected, [=]() { // 处理客户端断开连接的情况 socket->deleteLater(); // 清理资源 }); ``` 需要注意的是,在进行通信的过程中,可以根据具体需求设置超时时间、发送和接收数据等各种细节的处理。 另外,为了管理多个客户端连接,可以将QTcpSocket对象添加到一个容器中,例如使用QList或QVector等容器类。 以上是大致的实现思路,具体的细节和错误处理可以根据项目需求进行调整。 ### 回答2: Qt是一款跨平台的开发框架,拥有丰富的网络编程功能。要实现TCP连接多个客户端,可以采用Qt的QTcpServer和QTcpSocket类。 首先,创建一个QTcpServer对象,并调用其listen()函数,指定服务端的监听地址和端口号。然后,在新的客户端连接服务器时,QTcpServer会触发newConnection()信号。我们可以通过连接这个信号来处理新的客户端连接。 处理新连接的槽函数中,我们可以创建一个QTcpSocket对象,用于与客户端进行通信。通过调用QTcpServer的nextPendingConnection()函数,可以获取到与客户端连接的QTcpSocket对象。可以为每个客户端连接创建一个新的QTcpSocket对象。 为了处理多个客户端连接,我们可以使用一个QList或QVector来存储所有的QTcpSocket对象。在处理新连接的槽函数中,将新的QTcpSocket对象添加到列表中。这样我们就可以通过遍历列表,对每个客户端进行操作。 当服务端从某个客户端接收到数据时,可以通过connected()信号与readyRead()信号来读取数据。当服务端要发送数据给客户端时,可以调用QTcpSocket的write()函数。 如果某个客户端断开连接,QTcpSocket会触发disconnected()信号,我们可以在该信号的槽函数中将对应的QTcpSocket对象从列表中移除,并释放内存。 为了确保多个客户端可以同时进行连接和通信,可以使用多线程或者多线程框架(如QtConcurrent)来实现。每个客户端连接可以在一个单独的线程中进行处理。 总的来说,Qt提供了丰富的功能来处理TCP连接多个客户端。我们可以通过QTcpServer和QTcpSocket类来实现服务端与多个客户端之间的通信,使用容器来存储多个客户端连接对象,并使用多线程来处理多个客户端的并发连接。 ### 回答3: 在Qt中实现TCP连接多个客户端,我们可以使用Qt的网络模块来处理。 首先,我们需要创建一个TcpServer对象来接受客户端连接请求和处理数据传输。 然后,我们可以使用QObject的connect方法将TcpServer的newConnection信号与自定义的槽方法连接起来。在槽方法中,我们可以获取到新连接的SocketDescriptor,并创建一个TcpSocket对象来处理与客户端的通信。 在TcpSocket对象中,我们可以使用QObject的connect方法将TcpSocket的readyRead信号连接到自定义的槽方法上。在槽方法中,我们可以获取到客户端发送的数据,并进行相应的处理。 此外,我们还可以使用QObject的connect方法将TcpSocket的disconnected信号连接到自定义的槽方法上,用于处理客户端断开连接的情况。 在main函数中,我们可以创建多个TcpSocket对象,并连接到同一个TcpServer对象上,从而实现多个客户端同时连接的功能。 最后,我们可以通过TcpSocket的write方法向客户端发送数据,也可以通过TcpSocket的close方法主动关闭与客户端连接。 通过以上步骤,我们就可以实现Qt中TCP连接多个客户端的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值