LINUX--select服务器群发和回射

LINUX–select服务器群发和回射

#服务器
select()函数 控制文件描述符

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h> /* See NOTES */
#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;

vector 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;

}

上一篇:centos7下安装apache服务器httpd的yum方式安装


下一篇:php反序列化简叙