windows 下多socket连接(二)

来源:互联网 发布:猪肉绦虫知乎 编辑:程序博客网 时间:2024/06/05 12:45

在window下使用select实现多socket的连接修订版本


// WeChat.cpp : Defines the entry point for the console application.

//


#include "stdafx.h"
#include <stdio.h>
#include <string>
#include <vector>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")


#include "Util.h"


#define MAX_NUM 10
#define DATA_NUM 1024


using namespace std;


int sock_fd;
int client_fd[MAX_NUM];
struct fd_set read_set;
struct fd_set write_set;
struct fd_set select_read_set;
int max_fd;
int new_conn_fd;
struct timeval timeout = {0, 5000};
char recv_buf[DATA_NUM] = {0};




static DWORD WINAPI ThreadAccept(void *p);


void main(void )
{
sock_fd = -1;
max_fd = -1;
new_conn_fd = -1;
FD_ZERO(&read_set);
FD_ZERO(&write_set);
FD_ZERO(&select_read_set);


for (int i = 0; i < MAX_NUM; i++)
{
client_fd[i] = -1;
}



WORD wVersionRequested;
WSAData lpWSAData;
wVersionRequested = MAKEWORD(1, 1);


int err = WSAStartup(wVersionRequested, &lpWSAData);
if (!err)
{
printf("WSAStartup Succeed!\n");
}
else
{
printf("WSAStartup Fail!\n");
return ;
}


sock_fd = socket(AF_INET, SOCK_STREAM, 0);


SOCKADDR_IN serAdd;
serAdd.sin_family = AF_INET;
serAdd.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
serAdd.sin_port = htons(8000);
bind(sock_fd, (SOCKADDR *)&serAdd, sizeof(SOCKADDR));


listen(sock_fd, SOMAXCONN);


printf("server is running...\n");


HANDLE threadMsg = CreateThread(NULL, 0, ThreadAccept, NULL, 0, NULL);
if (threadMsg != NULL && threadMsg != INVALID_HANDLE_VALUE)
{
CloseHandle(threadMsg);
threadMsg = NULL;
}


while(1)
{
Sleep(1000);
}


WSACleanup();
}


DWORD WINAPI ThreadAccept(void *p)
{
printf("ThreadAccept start\n");
FD_SET(sock_fd, &read_set);
while(true)
{
max_fd = sock_fd;


for (int i = 0; i < MAX_NUM; i++)
{
if (max_fd < client_fd[i])
{
max_fd = client_fd[i];
}
}


select_read_set = read_set;


int ret = select(max_fd + 1, &select_read_set, NULL, NULL, &timeout);
if (ret == 0)
{
//printf("timeout\n");
}
else if (ret < 0)
{
printf("select error\n");
}
else
{
if (FD_ISSET(sock_fd, &select_read_set))
{
printf("new client comes\n");

SOCKADDR_IN clientAdd;
int len = sizeof(SOCKADDR);


new_conn_fd = accept(sock_fd, (SOCKADDR *)&clientAdd, &len);
if (new_conn_fd < 0)
{
printf("Fail to accept\n");
exit(1);
}
else
{
for (int i = 0; i < MAX_NUM; i++)
{
if (client_fd[i] == -1)
{
client_fd[i] = new_conn_fd;
FD_SET(new_conn_fd, &read_set);
break;
}
if (max_fd < new_conn_fd)
{
max_fd = new_conn_fd;
}
}
}
}
else
{
for (int i = 0; i < MAX_NUM; i++)
{
if (client_fd[i] == -1)
{
continue;
}


memset(recv_buf, 0, sizeof(recv_buf));


if (FD_ISSET(client_fd[i], &select_read_set))
{
int num = ::recv(client_fd[i], recv_buf, DATA_NUM, 0);
if (num < 0)
{
printf("Client(%d) left\n", client_fd[i]);  
FD_CLR(client_fd[i], &read_set);  
closesocket(client_fd[i]);
client_fd[i] = -1;  
}
else if (num > 0)
{
recv_buf[num] = '\0';
printf("Recieve client(%d) data\n", client_fd[i]);  
printf("Data: %s\n\n", recv_buf); 
}
else if (num == 0)
{
printf("Client(%d) exit\n", client_fd[i]);  
FD_CLR(client_fd[i], &read_set);  
closesocket(client_fd[i]);  
client_fd[i] = -1;  
}
}
}
}
}
}
printf("ThreadReceSendMsg end\n");
return 1;

}


在window平台select的第一个参数是可以忽略的,代码可以更简洁点

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 win7状态不可用怎么办 电脑的本地连接不见了怎么办 win7电脑没有本地连接怎么办 win7字体换不了怎么办 电脑没系统了怎么办 电脑系统没有了怎么办 系统调用区域小怎么办 win8.1网络受限怎么办 电脑连wifi受限怎么办 鼠标不好用了怎么办 手机指纹不好使怎么办 手机录像不好使怎么办 手机1个卡不好使怎么办 手机收藏不好使怎么办 window10连不上网怎么办 电脑没有家庭组怎么办 usb共享网络出错怎么办 电脑共享有密码怎么办 win10连不上网怎么办 w10网络重置了怎么办 点击网络重置后怎么办? 电脑启动找不到硬盘怎么办 电脑开机找不到硬盘怎么办 电脑找不到宽带连接怎么办 电脑文件找不到了怎么办 电脑找不到手机热点怎么办 win7电脑没有网络适配器怎么办 手机计算机桌面找不到怎么办 手机忘记开锁密码怎么办 电脑没网感叹号怎么办 本地连接2没有了怎么办 电脑上找不到本地连接怎么办 网络无访问权限怎么办 电脑无网络访问怎么办 xp连不上网怎么办 xp系统本地连接不见了怎么办 电脑xp系统本地连接怎么办 xp系统本地连接失败怎么办 xp系统找不到本地连接怎么办 台式电脑连不上网络怎么办 win7局域网要密码怎么办