2012年3月19日 星期一

[Socket 多線程]VC 2010

此篇為上一篇 [Socket]Vc 2010 之改進版本 可支援多client
Operating system:Win 7  32bit
Compiler:VC 2010



////////////////////////////////////////server code///////////////////////////////

#define _WIN32_WINNT 0x0400
#include <winsock.h>
#include <stdio.h>
#include <windows.h>
#pragma comment (lib,"ws2_32.lib")
#include <iostream>
using namespace std;
int count=0;

fd_set fd_AllConnection;



DWORD WINAPI ServerProc(LPVOID lParam)
{
char strBuffer[1024];
timeval t;
t.tv_sec=3;
t.tv_usec=0;
for(;;)
{

if(fd_AllConnection.fd_count==0) Sleep(100);

fd_set fd_Query=fd_AllConnection;
select(fd_Query.fd_count,&fd_Query,NULL,NULL,&t);
for(unsigned int i=0;i<fd_Query.fd_count;i++)
{

int nBytes=recv(fd_Query.fd_array[i],strBuffer,sizeof(strBuffer),0);
if(nBytes<=0)
{

FD_CLR(fd_Query.fd_array[i],&fd_AllConnection);  
closesocket(fd_Query.fd_array[i]);
count--;
//sprintf(strBuffer,"Client[%d]disconnect!",fd_Query.fd_array[i]);
cout << "Client ["<<fd_Query.fd_array[i]<<"] disconnect!"<<endl;
nBytes=(int) strlen(strBuffer);

}


}

}
}



void main()
{
int nRet;
WORD wVersion = MAKEWORD(1,1);
WSADATA wsa;
char pcname[ 1024 ];

nRet = WSAStartup( wVersion, &wsa );
gethostname( pcname, sizeof(pcname) );
cout<<pcname<<endl;                     //show your pc name

hostent *local;
local= gethostbyname( pcname );

const char* hostname = local->h_name;

local= gethostbyname( hostname );

struct in_addr *pinAddr;
pinAddr = ((LPIN_ADDR)local->h_addr_list[0]);
cout << "IP = " << inet_ntoa(*pinAddr) << endl;
cout<<"Listen for Client!"<<endl;
//////get ip address//////////////////////////////////////////
WSADATA wsData;
SOCKADDR_IN ServerAddr;
SOCKADDR_IN ClientAddr;
SOCKET ListenSocket;
SOCKET ClientSocket;
    WSAStartup(0x0202,&wsData);

ListenSocket= socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(ListenSocket==INVALID_SOCKET)
{
WSACleanup();
return;
}

memset(&ServerAddr,0,sizeof(ServerAddr));
ServerAddr.sin_family=AF_INET;
ServerAddr.sin_port=htons(IPPORT_ECHO);

bind(ListenSocket,(SOCKADDR*)&ServerAddr,sizeof(ServerAddr));

listen(ListenSocket,5); //max accept client
CreateThread(NULL,NULL,ServerProc,NULL,NULL,NULL);

int AddrLen=sizeof(ClientAddr);
for(;;)
{
ClientSocket=accept(ListenSocket,(SOCKADDR*)&ClientAddr,&AddrLen);
count++;                                 //count client number
cout<<count<<"  user online"<<endl;
if(ClientSocket==INVALID_SOCKET)
{

closesocket(ListenSocket);
WSACleanup();

return;
}
FD_SET(ClientSocket,&fd_AllConnection);
}

closesocket(ListenSocket);
closesocket(ClientSocket);
WSACleanup();

}

///////////////////////////////////////////////server code end//////////////////////////////////////////////////////


備註:
因為主要只有修改server端的code 使其能"Createthread "所以就不打上client的code

註解方面可以參考上一篇

沒有留言:

張貼留言