Linux-select模型

server端

#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include<stdlib.h>
#include<arpa/inet.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include<string.h>
using namespace std;

#define MAX_ACCEPT 4

int main() 
{
	//创建套接字
	/* 
	AF_INET : 地址格式
	SOCK_STREAM : 套接字类型
	IPPROTO_TCP : 协议类型
	*/
	int fd_server = socket(AF_INET, SOCK_STREAM, 0);//返回值为文件描述符
	if (fd_server == -1) 
	{
		cout << "failed socket !" << endl;
	}
	//填入sockaddr_in
	struct sockaddr_in sAddr = {};
	sAddr.sin_family = AF_INET;
	sAddr.sin_addr.s_addr = inet_addr("192.168.10.6");//ip地址
	sAddr.sin_port = htons(5566);
	//绑定IP地址和端口
	/*
	bind(
	fd : 文件描述符
	&sAddr : srtuct sockaddr*类型的指针,指向绑定IP地址和端口的结构体的地址
	sizeof(sAddr) : 绑定长度	
	*/
	if (bind(fd_server, (struct sockaddr*)&sAddr, sizeof(sAddr)) == -1) 
	{
		cout << "failed bind!" << endl;
	}
	//监听scoket_server
	int listen_server = listen(fd_server, 20);//20-指监听队列中允许保持的尚未处理的最大连接数量
	
//select模型

	int addrLen = sizeof(struct sockaddr);
	int client_fd[MAX_ACCEPT];
    sockaddr_in sockAddr[MAX_ACCEPT]={};
  	for (int i = 0;i<MAX_ACCEPT;i++){
    	client_fd[i] = -1;
	}
	client_fd[1] = fd_server;
	char IP[32];
	char message[20] = "Received";
	int max_fd = fd_server;//最大文件描述符
	fd_set fdRead;
	/*
	设置select函数等待的时间
	*/
	struct timeval time;
	time.tv_sec = 100;
	time.tv_usec = 1000;
	FD_ZERO(&fdRead);
	FD_SET(fd_server, &fdRead);

	while (1) 
	{	
		int nRet = select(max_fd+1, &fdRead, NULL, NULL, &time);
		if (nRet > 0) 
		{	
    		for (int i = 0; i < MAX_ACCEPT; i++)
			{	
				if (FD_ISSET(client_fd[i], &fdRead))//判断监听套接字是否有网络事件发生
			    {	
					if(client_fd[i] == fd_server)
					{		
    					client_fd[i] = accept(fd_server, (struct sockaddr*)&sockAddr[i], (socklen_t *)&addrLen);
							if (client_fd[i] == -1) 
							{
        						cout << "failed accept!" << endl;
								break;
							}
							max_fd = client_fd[i];
							cout<<"fd_connection_accept: "<<client_fd[i]<<endl;
							cout << "Connection successful " << endl;
							inet_ntop(AF_INET,(void *)&sockAddr[i].sin_addr.s_addr,IP,sizeof(IP));
							cout <<"IP Address "<<IP<<endl;
        					cout <<"ports "<<ntohs(sockAddr[i].sin_port)<<endl;
            				FD_SET(client_fd[i], &fdRead);

					}
            		else
					{
						char recv_data[20] = { 0 };
						int nRecv = read(client_fd[i], recv_data, 20);
						if (nRecv > 0) 
						{
							cout <<"fd : "<<client_fd[i]<< " recv data " << recv_data << endl;
							int send_flag = write(client_fd[i], message, strlen(message));								
						}
						else
						{
							cout << "failed!" << endl;
							close(client_fd[i]);
							FD_CLR(client_fd[i],&fdRead);
							break;
						}		
					}
				}
			}			
		}		
		else 
		{
			cout << "failed select!" << endl;
			break;
		}
	}
	return 0;
}

client端

​
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include<stdlib.h>
#include<arpa/inet.h>
#include<string.h>
using namespace std;

int main(int argv, char* argc[])
{
	//创建套接字
	int socket_client = socket(AF_INET, SOCK_STREAM, 0);
	sockaddr_in sockAddr = {};			
	sockAddr.sin_family = AF_INET;
	sockAddr.sin_addr.s_addr = inet_addr("192.168.10.6");//IP地址
	sockAddr.sin_port = htons(5566);
	if (connect(socket_client, (struct sockaddr*)&sockAddr, sizeof(sockAddr)) == -1) //发送连接请求
	{
			cout << "failed connect!" << endl;
			//return 0;
	}
	char message[40] = { 0 };
	while (1) 
	{
		cout << "Please input information:" << endl;
		char str1[] = {0};
		cin >> str1;
		int send_flag = write(socket_client, str1, strlen(str1) + sizeof(char));
		if (send_flag == -1) 
		{
			cout << "send failed!" << endl;
		}
		//Sleep(900);
		int recv_flag = read(socket_client, message, 40);
		if (recv_flag > 0) 
		{
			cout << "The data received is " << message << endl;
		}
	}
	//关闭套接字
	close(socket_client);
	system("pause");
	return 0;
}




​

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值