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的第一个参数是可以忽略的,代码可以更简洁点
阅读全文
0 0
- windows 下多socket连接(二)
- C++服务器(二):Windows下的socket编程
- WINDOWS环境下设置socket连接超时
- 判断socket是否连接(windows socket)
- 判断socket是否连接(windows socket)
- windows下socket 网络通信编程二
- windows下的socket的面向连接简单编程
- windows socket网络编程(二)
- LINUX下SOCKET连接
- Windows下VC编程(SOCKET)
- windows下的socket(1)
- windows 下SOCKET注意
- windows下 socket编程
- windows 下socket 编程
- Windows下使用socket,连接之前用非阻塞方式,连接成功后用阻塞方式
- Linux下Socket编程学习(二)
- linux下socket详解(二)
- windows、linux下java连接本地MQ队列实现输入(二)
- IQKeyboardManager使用导航上移问题
- Java类初始化
- Topic匹配模式
- java内存模型
- LightOJ 1401
- windows 下多socket连接(二)
- 使用formdata+ajax文件上传中遇到的问题
- 为什么计算机会有补码这种奇怪的规则?
- objective-C call
- LinkedList源码
- 致tensorflow
- 机器学习精简教程之九——用scikit-learn的网格搜索快速找到最优模型参数
- Android-UI绘制分析01
- Nginx无法启动也不报错