LINUX--サーバーグループの送信とエコーを選択します

LINUX-サーバーグループの送信とエコーを選択します


ファイル記述子を制御するサーバー選択()関数

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <sys / types.h> / *注を参照* /
#include <sys / socket.h>
#include <sys / socket.h>
#include <netinet / in.h>
#include <netinet / ip.h>
#include <arpa / inet.h>
#include <unistd.h>
#include <string.h>
#include <signal。 h>
#include <sys / ipc.h>
#include <sys / msg.h>
#include <sys / select.h>
#include
#include
using namespace std;

ベクトルvfds;
vector :: iterator it;

typedef struct chat
{ char name [16] = {0}; char text [1024] = {0};

} CHAT_T;

int main()
{ int socket_fd = socket(AF_INET、SOCK_STREAM、0); if(socket_fd == -1){ perror( "socket:");



}
struct sockaddr_in ser_add;
ser_add.sin_family = AF_INET;//ipv4
ser_add.sin_port = htons(8099);//转换为网络字节序
//inet_aton("146.56.129.60", &ser_add.sin_addr.s_addr);
ser_add.sin_addr.s_addr = htonl(INADDR_ANY);//对接本地任意的空闲ip
//ser_add.sin_addr.s_addr = htonl();//对接本地任意的空闲ip146.56.129.60 
 // 设置套接字选项避免地址使用错误  
int on = 1;
if ((setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) < 0)
{
	perror("setsockopt failed");
	exit(EXIT_FAILURE);
}

int ret = bind(socket_fd, (struct sockaddr*)&ser_add, sizeof(ser_add));
if (ret == -1)
{
	perror("bind:");

}
ret = listen(socket_fd, SOMAXCONN);
if (ret == -1)
{
	perror("listen:");

}

char buff[1024] = { 0 };

fd_set set;//集合
fd_set allset;//集合
FD_SET(socket_fd,&allset);
int maxfd = socket_fd;


while (1)
{
	set = allset;//做备份
	cout << "wait for slect..." << endl;
	int nres = select(maxfd+1,&set,NULL,NULL,NULL);//管理fd
	cout << "slect is return :" <<nres<< endl;
	//select 返回有两种情况
	if (FD_ISSET(socket_fd,&set)) 
	{
		struct sockaddr_in cli_add;
		socklen_t addrlen = sizeof(cli_add);
		int con_fd = accept(socket_fd, (struct sockaddr*)&cli_add, &addrlen);
		vfds.push_back(con_fd);
		cout << "current vfds:" << vfds.size() << endl;
		cout << "someone online" << "con_fd:" << con_fd << endl;
		//把新的客户端的fd交给select来管理
		FD_SET(con_fd, &allset);
		if (con_fd>maxfd) 
		{
			maxfd = con_fd;
		}

	
	}
	else 
	{
		for (it=vfds.begin();it!=vfds.end();it++) 
		{
		
			if (FD_ISSET(*it,&set))
			{
				int r_size=read(*it, (CHAT_T*)buff, sizeof(CHAT_T));
				if (r_size==0) //有客户端断开
				{
					cout << "one client esc:" <<*it<< endl;
					//把客户端从集合里删除
					FD_CLR(*it, &allset);
					vfds.erase(it);//vecor 删除
					break;

				}
				printf("%ssay:%s", ((CHAT_T*)buff)->name, ((CHAT_T*)buff)->text);
				//cout << "accept buff=" << ((CHAT_T*)buff)->name <<((CHAT_T*)buff)->text<<endl;
				//write(*it, buff, r_size);//回射
				//群发动作
				for (it = vfds.begin(); it != vfds.end(); it++)
				{
					write(*it, (CHAT_T*)buff, r_size);
				
				}
				bzero(buff,sizeof(buff));
				break;
			}

		}
		
		
	}
	
	
	


}






return 0;

}

おすすめ

転載: blog.csdn.net/z15005953031/article/details/113913828