INTERNET编程之SOCKET编程

我们就贴一个关于一个支持多个连接的的服务器和客户端代码吧.就是多个客户端可以同时连上服务器的例子,当然,只是测试玩玩而已,真正用的时候,还是要做必要的改进的,呵呵.

好了,我先贴出客户端吧:(记住要加上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)&param, 0, 0 );
   ++name;
   if( hThread ) CloseHandle( hThread );
  }
 }

 DeleteCriticalSection(&g_cs);
 closesocket( socket_server );

 WSACleanup();
}

你可以直接拷贝过去编译连接,就可以测试了,可以用于聊天的.如果你仔细改改就是一个很不错的聊天室工具了呢!呵呵!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值