我们就贴一个关于一个支持多个连接的的服务器和客户端代码吧.就是多个客户端可以同时连上服务器的例子,当然,只是测试玩玩而已,真正用的时候,还是要做必要的改进的,呵呵.
好了,我先贴出客户端吧:(记住要加上Ws2_32.lib库)
#include "WinSock2.h"
#include "conio.h"
#include "stdio.h"
void main()
{
/*-------------------------------------------*/
初始化套接字库
/*-------------------------------------------*/
WORD wVersionRequested; //版本号
WSADATA wsaData;
int ret;
wVersionRequested = MAKEWORD( 2, 2 ); //2.2版本的套接字
ret = WSAStartup( wVersionRequested, &wsaData );
if ( ret != 0 )
{
printf("加载套接字库失败!/n");
return ;
}
if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 )
{
printf("加载套接字库失败!/n");
WSACleanup();
return ;
}
/*-------------------------------------------*/
创建客户端
/*-------------------------------------------*/
hostent * pHost = NULL; //指向服务器主机的指针
SOCKET socket_client;
SOCKADDR_IN server; //服务器地址信息
pHost = gethostbyname( "127.0.0.1" );
if ( !pHost )
{
printf("无法解析服务器地址!错误原因:%d/n", WSAGetLastError() );
WSACleanup();
return ;
}
server.sin_addr.S_un.S_addr = *((DWORD*)pHost->h_addr_list[0]);
server.sin_family = AF_INET;
server.sin_port = htons(4443);
memset( server.sin_zero, 0, sizeof(server.sin_zero) );
socket_client = socket( AF_INET, SOCK_STREAM, 0 ); //创建套接字(socket)
if ( socket_client == INVALID_SOCKET )
{
printf("创建套接字失败!错误原因:%d/n", WSAGetLastError() );
WSACleanup();
return ;
}
if( SOCKET_ERROR == connect( socket_client , (SOCKADDR*)&server ,sizeof(SOCKADDR) ) )
{
printf( "连接服务器失败!错误原因:%d/n", WSAGetLastError() );
closesocket( socket_client );
WSACleanup();
return ;
}
do
{
char buffer[1024] = {0};
if( SOCKET_ERROR == recv( socket_client, buffer, 1023, 0 ) )
{
printf( "Error Occurs In recv : %d/n",WSAGetLastError() );
closesocket( socket_client );
return ;
}
printf( "recv : %s/n", buffer );
if ( strcmp(strupr(buffer),"QUIT") == 0 )
{
break;
}
printf( "Send:" );
scanf( "%s", buffer );
if( SOCKET_ERROR == send( socket_client, buffer, strlen(buffer) + 1, 0 ) )
{
printf( "发送数据失败!错误原因 : %d/n",WSAGetLastError() );
closesocket( socket_client );
WSACleanup();
return ;
}
if ( strcmp(strupr(buffer),"QUIT") == 0 )
{
break;
}
} while( TRUE );
printf("断开与服务器的连接!/n");
closesocket( socket_client );
WSACleanup();
}
下面的代码是相应的服务器端代码::(记住也要加上Ws2_32.lib库的)
#include "WinSock2.h"
#include "conio.h"
#include "stdio.h"
typedef struct _PARAMETER
{
char name;
SOCKET socket;
SOCKADDR_IN sock_addr;
}PARAMETER,*PPARAMETER;
CRITICAL_SECTION g_cs;
int g_nCount;
DWORD ThreadProc(
LPVOID lpParameter
)
{
char buffer[1024]= {0};
int nFirst = 0;
SOCKET socket_client;
SOCKADDR_IN client;
char name;
socket_client = ((PPARAMETER)lpParameter)->socket;
client = ((PPARAMETER)lpParameter)->sock_addr;
name = ((PPARAMETER)lpParameter)->name;
while( TRUE )
{
EnterCriticalSection( &g_cs );
memset( buffer, 0, 1024 );
if ( nFirst == 0 )
{
printf("There's a new connect!Come from %s/nSend To %c", inet_ntoa(client.sin_addr), name );
scanf( "%s", buffer );
nFirst = 1;
}
else
{
printf( "Send To %c: ", name );
scanf( "%s",buffer );
}
if( SOCKET_ERROR == send( socket_client, buffer, strlen(buffer) + 1, 0 ) )
{
printf( "Error Occurs In send : %d/n",WSAGetLastError() );
closesocket( socket_client );
LeaveCriticalSection(&g_cs);
return -1;
}
if ( strcmp(strupr(buffer),"QUIT") == 0 )
{
LeaveCriticalSection(&g_cs);
break;
}
memset( buffer, 0, 256 );
if( SOCKET_ERROR == recv( socket_client, buffer, 255, 0 ) )
{
printf( "Error Occurs In recv : %d/n",WSAGetLastError() );
closesocket( socket_client );
LeaveCriticalSection(&g_cs);
return -1;
}
printf( "Recv From %c : %s/n", name, buffer );
if ( strcmp(strupr(buffer),"QUIT") == 0 )
{
LeaveCriticalSection(&g_cs);
break;
}
LeaveCriticalSection(&g_cs);
}
printf( "断开与 %s 连接!/n", inet_ntoa(client.sin_addr) );
closesocket( socket_client );
return 0;
}
void main()
{
/*-------------------------------------------*/
只运行一个实例
/*-------------------------------------------*/
HANDLE hMutex = NULL;
hMutex = CreateMutex(NULL, FALSE, "Socket_Server");
if( hMutex )
{
if( GetLastError() == ERROR_ALREADY_EXISTS )
{
CloseHandle(hMutex);return ;
}
}
/*-------------------------------------------*/
初始化套接字库
/*-------------------------------------------*/
WORD wVersionRequested; //版本号
WSADATA wsaData;
int ret;
wVersionRequested = MAKEWORD( 2, 2 ); //2.2版本的套接字
ret = WSAStartup( wVersionRequested, &wsaData );
if ( ret != 0 )
{
printf("加载套接字库失败!/n");
return ;
}
if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 )
{
WSACleanup();
printf("加载套接字库失败!/n");
return ;
}
/*-------------------------------------------*/
创建服务器
/*-------------------------------------------*/
SOCKET socket_server = socket( AF_INET, SOCK_STREAM, 0 ); //创建套接字
SOCKADDR_IN server;
server.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
server.sin_family = AF_INET;
server.sin_port = htons(4443);
if( SOCKET_ERROR == bind( socket_server, (SOCKADDR*)&server, sizeof(SOCKADDR) ) )
{
printf( "Error Occurs In bind : %d/n",WSAGetLastError() );
closesocket( socket_server );
WSACleanup();
return ;
}
if( SOCKET_ERROR == listen( socket_server, 5 ) )
{
printf( "Error Occurs In listen : %d/n",WSAGetLastError() );
closesocket( socket_server );
WSACleanup();
return ;
}
InitializeCriticalSection(&g_cs);
while ( TRUE )
{
SOCKET socket_client;
SOCKADDR_IN client;
int nLen = sizeof(SOCKADDR);
socket_client = accept( socket_server, (SOCKADDR*)&client, &nLen ); //等待客户端连接(阻塞)
if ( socket_client == INVALID_SOCKET )
{
printf( "Error Occurs In accept : %d/n",WSAGetLastError() );
}
else
{
HANDLE hThread;
PARAMETER param;
static char name = 'A';
param.socket = socket_client;
param.sock_addr = client;
param.name = name;
hThread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc, (LPVOID)¶m, 0, 0 );
++name;
if( hThread ) CloseHandle( hThread );
}
}
DeleteCriticalSection(&g_cs);
closesocket( socket_server );
WSACleanup();
}
你可以直接拷贝过去编译连接,就可以测试了,可以用于聊天的.如果你仔细改改就是一个很不错的聊天室工具了呢!呵呵!