// 一个监听线程, 每当一个新的客户端连接进来时会再创建一个新的线程供连接
#include "stdafx.h"
#include <winsock2.h>
#include <iostream>
#pragma comment( lib, "ws2_32.lib" )
const static int BUF_SIZE =
256;
using namespace std;
#define MAIN_RETURN_ERROR
-1;
#define MAIN_RETURN_NORMAL
0;
DWORD WINAPI AnswerThread( LPVOID lparam );
sockaddr_in addrClient;
int addrClientLen = sizeof( addrClient );
int _tmain( int argc , _TCHAR* argv[])
{
// 初始化Winsock
2.2
WSADATA wsaData ;
if( WSAStartup ( MAKEWORD(
2, 2 ), & wsaData )
!= 0 )
{
cout<<"WSAStartup 无法初始化 !" <<endl ;
return MAIN_RETURN_ERROR ;
}
// 通过WinSock 实现网络通信
SOCKET sServer ;
// 创建用于监听的Socket
sServer = socket ( AF_INET, SOCK_STREAM, IPPROTO_TCP );
if( INVALID_SOCKET == sServer )
{
cout<<"Socket
Failed !" <<endl;
WSACleanup();
return MAIN_RETURN_ERROR ;
}
// 设置服务器Socket 地址
SOCKADDR_IN addrServ ;
addrServ.sin_family
= AF_INET;
addrServ.sin_port
= htons(
9990 ); // 服务器端口号
addrServ.sin_addr .S_un. S_addr = htonl ( INADDR_ANY );
// 绑定
int retVal ;
retVal = bind ( sServer,
( const struct sockaddr *)&addrServ , sizeof( SOCKADDR_IN )
);
if( SOCKET_ERROR == retVal )
{
cout<<"bind
failed !" <<endl;
closesocket( sServer );
WSACleanup();
return -1;
}
// 监听
retVal = listen ( sServer,
1 );
if( SOCKET_ERROR == retVal )
{
cout<<"listen
failed !" <<endl;
closesocket( sServer );
WSACleanup();
return -1;
}
// 设置socket 其为非阻塞模式 ,
argp 设为非零值
int iModel =
1;
retVal = ioctlsocket ( sServer, FIONBIO,
(u_long FAR*
)&iModel );
if( SOCKET_ERROR == retVal )
{
cout<<"ioctlsocket
failed " <<endl;
WSACleanup();
return MAIN_RETURN_ERROR ;
}
cout<<"TCP
Server Start ... ..." <<endl;
// 循环等待
while( true )
{
SOCKET sClient = accept( sServer,
( sockaddr FAR*)&addrClient ,
&addrClientLen );
if( INVALID_SOCKET == sClient )
{
int err = WSAGetLastError();
if( WSAEWOULDBLOCK == err ) // 没接到连接请求
{
Sleep(
100 );
continue;
}
else
{
cout<<"accept
failed" <<endl;
closesocket( sServer );
WSACleanup();
return MAIN_RETURN_ERROR ;
}
}
// 接到了创建一个新线程供新的客户端使用
DWORD dwThreadId ;
CreateThread( NULL , NULL, AnswerThread,
(LPVOID )sClient,
0, & dwThreadId );
}
// 最后做一些清理工作
closesocket( sServer );
WSACleanup();
system("pause" );
return MAIN_RETURN_NORMAL ;
}
DWORD WINAPI AnswerThread( LPVOID lparam )
{
// 循环接受客户端发送来的请求,直到客户端发送 quit 命令
char buf [BUF_SIZE];
int retVal ;
SOCKET sClient =
(SOCKET)( LPVOID)lparam ;
while( true )
{
ZeroMemory( buf , BUF_SIZE );
retVal = recv ( sClient, buf, BUF_SIZE ,
0 );
if( SOCKET_ERROR == retVal )
{
int err = WSAGetLastError();
if( WSAEWOULDBLOCK == err )
{
Sleep(
100 );
continue;
}
else if ( WSAETIMEDOUT == err || WSAENETDOWN == err ) // 网络系统故障
{
cout<<"recv
failed !" <<endl;
closesocket( sClient );
WSACleanup();
return MAIN_RETURN_ERROR ;
}
}
SYSTEMTIME st ;
GetLocalTime(
&st );
char sDateTime [30];
sprintf( sDateTime , "%4d-%2d-%2d
%2d:%2d:%2d", st.wYear , st. wMonth, st .wDay, st.wHour , st. wMinute, st.wSecond );
cout<<sDateTime <<"
, Recv From Client [ "<< inet_ntoa( addrClient .sin_addr )<<":" <<addrClient. sin_port<<"]:
" <<buf<< endl;
if(
0 == strcmp ( buf, "quit" )
)
{
retVal = send ( sClient, "quit", strlen ("quit"),
0 );
break;
}
else
{
char msg [BUF_SIZE];
sprintf( msg , "Message
receive - %s ", buf );
while( true )
{
retVal = send ( sClient, msg, strlen ( msg ),
0 );
if( SOCKET_ERROR == retVal )
{
int err = WSAGetLastError();
if( WSAEWOULDBLOCK == err )
{
Sleep(
100 );
continue;
}
else
{
cout<<"send
failed !" <<endl;
closesocket( sClient );
WSACleanup();
return MAIN_RETURN_ERROR ;
}
}
else
break;
}
}
}
closesocket( sClient );
}