非阻塞 TCP协议下多用户的服务器
来源:互联网 发布:深度linux系统写python 编辑:程序博客网 时间:2024/06/05 15:27
// 一个监听线程, 每当一个新的客户端连接进来时会再创建一个新的线程供连接
#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 );
}
0 0
- 非阻塞 TCP协议下多用户的服务器
- linux下非阻塞的tcp研究
- linux下非阻塞的tcp研究
- linux下非阻塞的tcp研究
- linux下非阻塞的tcp研究
- linux下非阻塞的tcp研究
- linux下非阻塞的tcp研究
- 使用OTP原理构建一个非阻塞的TCP服务器
- linux下非阻塞的tcp认识与理解
- Linux下TCP非阻塞连接的方法
- 非阻塞式TCP 服务器/客户端 基础
- Java 服务器非阻塞模式下的例子
- TCP 阻塞模型下服务器和客户端的建立步骤
- TCP 阻塞模型下服务器和客户端的建立步骤
- Linux下的单进程多用户TCP服务器,采用select方法实现。
- linux 下非阻塞客户端,服务器代码
- NIO实现TCP的非阻塞通信
- TCP socket 非阻塞
- AsyncTask的使用
- ASE sysmon监控分析_网络IO
- XSD工具使用方法介绍
- 最小生成树--Kruskal
- 利用辗转相除法求最小公倍数,最大公约数
- 非阻塞 TCP协议下多用户的服务器
- C++头文件
- 『Linux』用SecureCRT远程登录,自动切到root账户的问题
- 【创业公司如何分配股份期权?】
- 线程与进程的区别于联系
- 详解Adorner Layer
- Work Progress
- 计算机核心期刊排名及投稿经验
- Ubuntu 12.04 使用基本配置