#include "stdafx.h"
#pragma comment(lib, "Ws2_32.lib")
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <windows.h>
#include <process.h>
#define PORT 5038
#define CONCOUNTS 5
#define COMLENGTH 256
typedef struct crossThread
{
SOCKET confd[CONCOUNTS]; //no lock.
HANDLE conEvent;
}crossThread;
void initSocket();
unsigned int __stdcall ThreadFunSendData(PVOID pM); //is better than CreateThread
unsigned int __stdcall ThreadFunRecvData(PVOID pM);
unsigned int __stdcall ThreadFunKeepConn(PVOID pM);
int _tmain(int argc, _TCHAR* argv[])
{
initSocket(); //windows special setting
int i=0;
const int THREAD_NUM = 3;
HANDLE handle[THREAD_NUM];
crossThread pM;
for(i = 0; i< CONCOUNTS;i++)
{
pM.confd[i] = 0;
}
pM.conEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
handle[0] = (HANDLE)_beginthreadex(NULL, 0, ThreadFunSendData, (PVOID)&pM, 0, NULL);
handle[1] = (HANDLE)_beginthreadex(NULL, 0, ThreadFunRecvData, (PVOID)&pM, 0, NULL);
handle[2] = (HANDLE)_beginthreadex(NULL, 0, ThreadFunKeepConn, (PVOID)&pM, 0, NULL);
WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE);
for(i = 0; i< THREAD_NUM;i++)
CloseHandle(handle[i]);
CloseHandle(pM.conEvent);
WSACleanup();
system("PAUSE");
}
void initSocket() //for winsocket dll.
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(2, 2);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0) {
/* Tell the user that we could not find a usable */
/* Winsock DLL. */
printf("WSAStartup failed with error: %d\n", err);
return;
}
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
printf("Could not find a usable version of Winsock.dll\n");
WSACleanup();
return;
}
else
printf("The Winsock 2.2 dll was found okay\n");
}
unsigned int __stdcall ThreadFunSendData(PVOID _pM)
{
crossThread* pM = (crossThread*)_pM;
char commandString[COMLENGTH];
int stringLength=0;
int sendResult =0 ,i = 0;
while(1)
{
gets(commandString);
stringLength =strlen(commandString);
if (stringLength >0)
{
for(i=0;i<CONCOUNTS;i++) //broadcast to every clients
{
sendResult =send(pM->confd[i],commandString,stringLength,0);
}
}
}
return 0;
}
unsigned int __stdcall ThreadFunRecvData(PVOID _pM)
{
crossThread* pM = (crossThread*)_pM;
char commandString[COMLENGTH] ={0};
int recvLength=0,i =0;
/////////////////////////////////////
FD_SET readSet;
FD_ZERO(&readSet);
//////////////////////////////////
while(1)
{
WaitForSingleObject(pM->conEvent,INFINITE);
for(i=0; i<CONCOUNTS;i++)
{
if (pM->confd[i] >0)
{
FD_SET(pM->confd[i],&readSet);
}
}
int ret=select(0,&readSet,NULL,NULL,NULL); //wait for different client msg
for(i=0; i<CONCOUNTS;i++)
{
if(FD_ISSET(pM->confd[i],&readSet))
{
recvLength =recv(pM->confd[i],commandString,COMLENGTH,0);
if (recvLength >0)
{
printf("recv:%s\n",commandString);
memset(commandString,0,COMLENGTH);
SetEvent(pM->conEvent);
}
}
}
}
}
unsigned int __stdcall ThreadFunKeepConn(PVOID _pM)
{
crossThread* pM = (crossThread*)_pM;
int connId =0;
SOCKADDR_IN client;
socklen_t addrlen;
addrlen =sizeof(client);
SOCKET sockSrv;
SOCKADDR_IN addrServ;
sockSrv = socket(AF_INET, SOCK_STREAM, 0);
int opt =SO_REUSEADDR;
setsockopt(sockSrv,SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt));
memset(&addrServ,0,sizeof(addrServ));
addrServ.sin_family=AF_INET;
addrServ.sin_port=htons(PORT);
addrServ.sin_addr.S_un.S_addr= htonl (INADDR_ANY);
bind(sockSrv, (struct sockaddr *)&addrServ, sizeof(addrServ));
listen(sockSrv,8);
while(1)
{
pM->confd[connId] = accept(sockSrv,(struct sockaddr*)&client,&addrlen);//maybe use select is better.
SetEvent(pM->conEvent);
connId=(connId+1)%CONCOUNTS;
}
for (connId = 0 ;connId< CONCOUNTS;connId++)
{
closesocket(pM->confd[connId]);
}
closesocket(sockSrv);
return 0;
}
windows tcp服务器代码,多线程+select
最新推荐文章于 2024-06-05 22:33:22 发布