window socket多连接的实现

来源:互联网 发布:windows old有什么用 编辑:程序博客网 时间:2024/05/16 14:59

直接上代码,代码可能不完美,主要是透过代码理解多连接的思想:


// 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")


#define MAX_SIZE 10


using namespace std;


FILE *ffp;
std::vector<SOCKET> v_sock;
SOCKET serSocket;
struct fd_set rfds;
struct timeval timeout = {0, 200};
char *readbuff[10] = {0};
string ss;


char sztext[1024] = { 0 };
char sztext1[1024] = { 0 };


static DWORD WINAPI ThreadAccept(void *p);
static DWORD WINAPI ThreadReceSendMsg(void *p);




void main(void )
{
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 ;
}


serSocket = 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(serSocket, (SOCKADDR *)&serAdd, sizeof(SOCKADDR));


listen(serSocket, SOMAXCONN);


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


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


HANDLE threadMsg = CreateThread(NULL, 0, ThreadReceSendMsg, 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");
SOCKADDR_IN clientAdd;
SOCKET clientCon;
int len = sizeof(SOCKADDR);
while(1)
{
if (v_sock.size() < MAX_SIZE)
{
for(int i = v_sock.size(); i < MAX_SIZE; ++i)
{
clientCon = accept(serSocket, (SOCKADDR *)&clientAdd, &len);
if (clientCon != INVALID_SOCKET)
{
v_sock.push_back(clientCon);
printf("%s is connected!\n", inet_ntoa(clientAdd.sin_addr));
}
}
printf("Server connected is full!\n");
}
}


printf("ThreadAccept end\n");
return 1;
}


DWORD WINAPI ThreadReceSendMsg(void *p)
{
printf("ThreadReceSendMsg start\n");
while(true)
{
for(int i = 0; i < v_sock.size(); ++i)
{
FD_ZERO(&rfds);
FD_SET(v_sock.at(i), &rfds);


switch(select(0, &rfds, NULL, NULL, &timeout))
{
case -1:
{
v_sock.erase(v_sock.begin() + i);
printf("client is disconnected!\n");
}
break;
case 0:
continue;
default:
if (FD_ISSET(v_sock.at(i), &rfds))
{
if (::recv(v_sock.at(i), sztext1, sizeof(sztext1), 0) != -1)
{
printf("%s\r\n", sztext1);
}
else
{
v_sock.erase(v_sock.begin() + i);
printf("client is disconnected\n");
continue;
}


ss = "have recv ";
ss += sztext1;
strcpy(sztext, ss.c_str());
for (int j = 0; j < v_sock.size(); ++j)
{
::send(v_sock.at(j), sztext, sizeof(sztext), 0);
}
}
}
}
}
printf("ThreadReceSendMsg end\n");
return 1;
}

原创粉丝点击