select模式学习(二)之:客户端

#include "stdafx.h"

////////////////////////////////////////////
//
//  TCP Client  非阻塞模式设定
//
////////////////////////////////////////////

#pragma  comment(lib,"ws2_32.lib")

#include <WinSock2.h>

#define CONNECT_IP        "127.0.0.1"
#define CONNECT_PORT      1207
#define DEFAULT_BUFF_LEN  256
int _tmain(int argc, _TCHAR* argv[])
 {
 WSAData       wsData;
 SOCKET        sServer;
 SOCKADDR_IN   addrServer;
 SOCKADDR_IN   addrLocal;
 char          sendBuff[DEFAULT_BUFF_LEN]={0};
 char          recvBuff[DEFAULT_BUFF_LEN]={0};
 int           nError;
 printf(">>>>>TCP 客户端启动<<<<<<\n");
 WSAStartup( MAKEWORD(2,2), &wsData );
 printf("-创建客户端用SOCKET\n");
 sServer = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
 if( sServer == INVALID_SOCKET )
  {
  printf("!!! socket failed: %d\n", WSAGetLastError());
  WSACleanup();
  return -1;
  }
 addrServer.sin_family = AF_INET;
 addrServer.sin_addr.S_un.S_addr = inet_addr( CONNECT_IP );
 addrServer.sin_port = htons(CONNECT_PORT);
 printf("-设定服务器地址信息: %s:%d\n",inet_ntoa(addrServer.sin_addr), ntohs(addrServer.sin_port));

 //设定本地用地址和端口
 //addrLocal.sin_family = AF_INET;
 //addrLocal.sin_addr.S_un.S_addr = inet_addr( CONNECT_IP );
 //addrLocal.sin_port = htons( 2701 );
 //printf("-绑定本地用地址和端口: %s:%d\n", inet_ntoa(addrLocal.sin_addr), ntohs(addrLocal.sin_port));
 ////nError = bind( sServer, (const sockaddr*)&addrLocal, sizeof(addrLocal) );
 //if( nError == SOCKET_ERROR )
 // {
 // printf("!!! bind failed: %d\n", WSAGetLastError());
 // WSACleanup();
 // return -1;
 // }

 printf("-连接指定服务器\n");
 nError = connect( sServer, (const sockaddr*)&addrServer, sizeof(addrServer) );
 if( nError == SOCKET_ERROR )
  {
  printf("!!! connect failed: %d\n", WSAGetLastError());
  closesocket( sServer );
  WSACleanup();
  return -1;
  }
 ///////////////////////////////////
 //  客户端 SOCKET为非阻塞模式
 //
 ///////////////////////////////////
 DWORD nMode = 1;
 nError = ioctlsocket( sServer, FIONBIO, &nMode );
 if( nError == SOCKET_ERROR )
  {
  printf("!!! ioctlsocket failed: %d\n", WSAGetLastError());
  closesocket( sServer );
  WSACleanup();
  return -1;
  }
 printf("-SOCKET模式设定: %s\n", (nMode==0?"阻塞模式设定":"非阻塞模式设定"));

 printf("-开始准备送信受信\n");
 int nInputLen = 0;
 int nIndex    = 0;
 int nLeft     = 0;
 fd_set  fdRead;
 fd_set  fdWrite;
 timeval tv={10,0};
 while(true)
  {
  FD_ZERO( &fdRead );
  FD_ZERO( &fdWrite );
  FD_SET( sServer, &fdRead );
  FD_SET( sServer, &fdWrite );
  nError = select( 0, &fdRead, &fdWrite, NULL, &tv );
  if( nError == 0 )
   {
   printf("!!! select time out\n");
   continue;
   }
  else if( nError < 0 )
   {
   printf("!!! select failed: %d\n", WSAGetLastError());
   break;
   }


  //发现SOCKET可读/可写
  if( FD_ISSET( sServer, &fdRead) )
   {
   memset( recvBuff, 0, sizeof(recvBuff) );
   nError = recv( sServer, recvBuff, sizeof(recvBuff)-1, 0 );
   ;;;;;if( nError == SOCKET_ERROR )
    {
    printf("!!! recv failed: %d\n", WSAGetLastError());
    break;
    }
   else if( nError == 0 )
    {
    printf("-Server Has Closed.\n");
    break;
    }
   recvBuff[nError] = '\0';
   printf("-Received: %s\n\n", recvBuff);
   }
  if( FD_ISSET(sServer, &fdWrite) )
   {
   printf("Input Message You Want to Send( Quit ):\n");
   fflush( stdin );
   memset( sendBuff, 0, sizeof(sendBuff) );
   fgets( sendBuff, sizeof(sendBuff)-1, stdin );
   nInputLen = strlen( sendBuff );
   sendBuff[nInputLen-1] = '\0';//去掉回车符
   --nInputLen;
   nIndex = 0;
   nLeft  = nInputLen;
   if(strcmp(sendBuff, "Quit")==0)
    {
    break;
    }
   //将输入的数据发送过去
   while( nLeft > 0)
    {
    nError = send( sServer, &sendBuff[nIndex], nLeft, 0 );
    ;;;;if( nError == SOCKET_ERROR )
     {
     printf("!!! send failed: %d\n",WSAGetLastError());
     closesocket( sServer );
     WSACleanup();
     return -1;
     }
    else if( nError == 0 )
     {
     printf("-Send OK.\n");
     break;
     }

    nLeft  -= nError;
    nIndex += nError;
    }
   printf("-Has send: %s\n",sendBuff);
   }
  }//while(true)

 printf("-关闭SOCKET\n");
 closesocket(sServer);
 WSACleanup();
 return 0;
 }

你可能感兴趣的:(select)