现在的位置: 首页 > 综合 > 正文

[精通WindowsSocket网络开发-基于VC++实现]第四章——阻塞模式开发

2013年04月27日 ⁄ 综合 ⁄ 共 21070字 ⁄ 字号 评论关闭

套接字的阻塞模式是指套接字在执行操作时,调用函数在没有完成操作之前不会立即返回的工作模式。阻塞模式的套接字用于少量数据接收和发送的简单网络程序开发。

套接字的阻塞模式

WindowsSockets分别提供了套接字模式和套接字I/O模型,可以对一个套接字的行为进行控制。套接字模式用于当一个套接字被调用时,决定调用函数的阻塞行为。套接字模式有阻塞和非阻塞两种工作模式。套接字I/O模型描述了一个应用程序如何对套接字上的I/O进行管理。套接字和套接字I/O模型是两个不同的概念且他们之间是无关的。本章详细介绍套接字阻塞模式。第五章讲解
非阻塞模式,套接字
IO模型有(Select模型,WSAAsyncSelect模型,WSAEventSelect模型,重叠I/O模型,完成端口模型)他们分别在第六、七、八、九、十章讲解

阻塞模式

WindowsSockets在阻塞和非阻塞两种模式下执行I/O操作。在阻塞模式下,在I/O操作完成前,执行的操作函数将一直等候而不会立即返回,该函数所在的线程会阻塞在这里。相反,在非阻塞模式下,套接字函数会立即返回,而不管I/O是否完成,该函数所在的线程会继续运行。

在阻塞模式的套接字上,调用任何一个WindowsSockets API都会消耗不确定的等待时间。在调用recv()时,发生在内核中等待数据和复制数据的过程如下:

当调用recv()时,系统首先检查是否有准备好的数据。如果数据没有准备好,系统就处于等待状态。当数据准备好后,将数据从系统缓冲区复制到用户空间,然后该函数返回。在套接应用程序中,当调用recv()时,用户空间未必就已经存在数据,此时recv()函数就是会处在等待状态。

设置套接字的阻塞模式

在使用socket()WSASocket()创建套接字时,默认的套接字都是阻塞的。这意味着当调用WindowsSocketsAPI不能立即完成时,线程处于等待状态,直到操作完成。

并不是所有的WindowsSocketsAPI以阻塞套接字为参数调用都会发生阻塞。egbind(),listen()时,函数会立即返回。这里将可能阻塞套接字的WindowsSocketsAPI调用分为以下4

  • 输入操作:recv(),recvfrom(),WSARecv(),WSARecvfrom()。以阻塞套接字为参数调用这些函数接收数据,如果此时套接字缓冲区内没有数据可读,则调用线程在数据到来前一直睡眠。
  • 输出操作:send(),sendto(),WSASend(),WSASendto()。以阻塞套接字为参数调用这些哈思楠发送数据。如果套接字缓冲区没有可用空间,线程会一直睡眠,直到有空间。
  • 接收连接:accept(),WSAAcept()。以阻塞套接字为参数调用这些函数,将等待接受对方的连接请求,如果此时没有连接请求,线程就会进入睡眠状态。
  • 外出连接:connect(),WSAConnect()。对于TCP连接,客户端以阻塞套接字为参数,调用这些函数向服务器发起连接。该函数在收到服务器的应答前,不会返回。这就意味着TCP连接总会等待至少从客户端到服务器的一次往返的时间。

阻塞模式套接字的优势和不足

使用阻塞模式的套接字开发网络程序比较简单,容易实现。当希望能够理解发送和接收数据,且处理的套接字数量比较少的情况下,使用阻塞模式来开发网络程序比较合适。

阻塞模式套接字的不知表现为,在大量建立好的套接字线程之间进行通信时比较困难。当使用“生产者——消费者”模型开发网络程序时,为每个套接字都分别分配一个读线程,一个处理数据线程和一个用于同步的事件,无疑加大了系统的开销。阻塞模式套接字的最大的缺点是当希望同时处理大量套接字时,将无从下手,扩展性差。

客户端与服务器端相互问候

BlockServer

  1. // BlockServer.cpp : 定义控制台应用程序的入口点。 
  2.   
  3. #include <stdio.h> 
  4. #include <WinSock2.h> 
  5. #pragma comment(lib,"ws2_32.lib") 
  6. #define BUF_SIZE 64 
  7. SOCKET sServer;//服务器监听套接字 
  8. SOCKET sClient;//接收客户端套接字   
  9. void RecvLine(SOCKET s,char* buf);//读取一行数据 
  10. void main() 
  11.     char bufRecv[BUF_SIZE]; 
  12.     char bufSend[BUF_SIZE]; 
  13.     memset(bufSend,0,BUF_SIZE); 
  14.     memset(bufRecv,0,BUF_SIZE); 
  15.     sServer=INVALID_SOCKET; 
  16.     sClient=INVALID_SOCKET;  
  17.  
  18.     WSADATA wsd; 
  19.     if (WSAStartup(MAKEWORD(2,2),&wsd) != 0)//初始化Windows Sockets DLL 
  20.     { 
  21.         printf("WSAStartup() failed,errno=%d\n",GetLastError()); 
  22.         return
  23.     } 
  24.     if (LOBYTE(wsd.wVersion) != 2 || HIBYTE(wsd.wVersion) != 2)//确保WinSock DLL支持2.2 
  25.     { 
  26.         printf("can not find a usabe windwos sockets dll!"); 
  27.         WSACleanup(); 
  28.         return
  29.     } 
  30.     if ((sServer=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) == INVALID_SOCKET)//创建套接字 
  31.     { 
  32.         printf("socket() failed,errno=%d\n",WSAGetLastError()); 
  33.         WSACleanup(); 
  34.         return
  35.     } 
  36.     //服务器套接字地址  
  37.     SOCKADDR_IN addrServ; 
  38.     addrServ.sin_family=AF_INET; 
  39.     addrServ.sin_addr.S_un.S_addr=INADDR_ANY;//在程序中使用INADDR_ANY值作为网络地址,这意味着网络服务器提供者将使用合适的网络地址进行绑定。 
  40.     addrServ.sin_port=htons(5000); 
  41.     if (bind(sServer,(SOCKADDR*)&addrServ,sizeof(addrServ)) == SOCKET_ERROR)//绑定套接字 
  42.     { 
  43.         printf("bind() failed,errno=%d\n",WSAGetLastError()); 
  44.         closesocket(sServer); 
  45.         WSACleanup(); 
  46.         return
  47.     } 
  48.  
  49.     if ((listen(sServer,2)) == SOCKET_ERROR)//开始监听 
  50.     { 
  51.         closesocket(sServer); 
  52.         WSACleanup(); 
  53.         return
  54.     } 
  55.     printf("Server succeded!\nWaiting for new clients...\n");//等待客户端的连接 
  56.  
  57.     SOCKADDR_IN addrClient; 
  58.     int addrClientLen=sizeof(addrClient); 
  59.     if ((sClient=accept(sServer,(SOCKADDR*)&addrClient,&addrClientLen)) == INVALID_SOCKET)//接受客户端请求 
  60.     { 
  61.         printf("accept() failed,errno=%d\n",WSAGetLastError()); 
  62.         closesocket(sServer); 
  63.         WSACleanup(); 
  64.         return
  65.     }  
  66.     //显示客户端的IP和端口 
  67.     char* pClientIP=inet_ntoa(addrClient.sin_addr); 
  68.     u_short clientPort=ntohs(addrClient.sin_port); 
  69.     printf("accept a client[%s]:%d\n",pClientIP,clientPort); 
  70.  
  71.     RecvLine(sClient,bufRecv);//接收客户端数据 
  72.     printf("recv client info:%s\n",bufRecv); 
  73.  
  74.     strcpy(bufSend,"Hello,Client!\n"); 
  75.     if (send(sClient,bufSend,strlen(bufSend),0) == SOCKET_ERROR)//向客户端发送数据 
  76.     { 
  77.         printf("send() failed,errno=%d\n",WSAGetLastError()); 
  78.         closesocket(sClient); 
  79.         closesocket(sServer); 
  80.         WSACleanup(); 
  81.         return
  82.     } 
  83.     printf("server exiting...\n");//显示退出信息      
  84.     closesocket(sClient); 
  85.     closesocket(sServer); 
  86.     WSACleanup(); 
  87.     system("pause"); 
  88.     return
  89.  
  90. void RecvLine(SOCKET s,char* buf) 
  91.     BOOL bLineEnd=FALSE;//行结束 
  92.     int nReadLen=0;//读入字节数 
  93.     int nDataLen=0;//数据长度 
  94.     while(!bLineEnd) 
  95.     { 
  96.         if ((nReadLen=recv(s,buf+nDataLen,1,0)) == SOCKET_ERROR)//每次读取一个字节 
  97.         { 
  98.             printf("recv() failed,errno=%d\n",WSAGetLastError()); 
  99.             closesocket(s); 
  100.             closesocket(sServer); 
  101.             WSACleanup(); 
  102.             return
  103.         } 
  104.         if (nReadLen == 0) 
  105.         { 
  106.             printf("读数据失败"); 
  107.             break;//跳出循环 
  108.         } 
  109.         if ('\n' == *(buf+nDataLen))//换行符 
  110.         { 
  111.             bLineEnd=TRUE;//接收数据结束 
  112.         }  
  113.         else 
  114.         { 
  115.             nDataLen+=nReadLen;//增加数据长度 
  116.         } 
  117.     }  
  118. }  

BlockClient

  1. // BlockClient.cpp : 定义控制台应用程序的入口点。 
  2.   
  3. #include <WinSock2.h> 
  4. #include <stdio.h> 
  5. #pragma comment(lib,"ws2_32.lib") 
  6. #define BUF_SIZE 64 
  7. void RecvLine(SOCKET s,char* buf);//读取一行数据 
  8. void main() 
  9.     WSADATA wsd; 
  10.     if (WSAStartup(MAKEWORD(2,2),&wsd) != 0)//初始化套接字动态库 
  11.     { 
  12.         printf("WSAStartup() failed! erron=%d\n",GetLastError()); 
  13.         return
  14.     } 
  15.  
  16.     SOCKET sClient;//服务器套接字 
  17.     if ((sClient=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) == INVALID_SOCKET)//创建套接字 
  18.     { 
  19.         printf("socket() failed! errno=%d\n",WSAGetLastError()); 
  20.         WSACleanup();//释放套接字资源 
  21.         return
  22.     } 
  23.  
  24.     //获取主机的信息 
  25.     hostent* hostEntry; 
  26.     char hostname[BUF_SIZE]; 
  27.     gethostname(hostname,BUF_SIZE); 
  28.     if(!(hostEntry=gethostbyname(hostname))) 
  29.     { 
  30.         printf("gethostbyname() failed,errno=%d\n",GetLastError()); 
  31.         closesocket(sClient);//关闭套接字 
  32.         WSACleanup(); 
  33.         return
  34.     } 
  35.  
  36.     //设置服务器地址 
  37.     SOCKADDR_IN addrServ; 
  38.     addrServ.sin_family=AF_INET; 
  39.     addrServ.sin_addr =*((LPIN_ADDR)*hostEntry->h_addr_list); 
  40.     addrServ.sin_port=htons(5000); 
  41.     if (connect(sClient,(SOCKADDR*)&addrServ,sizeof(addrServ)) == SOCKET_ERROR)//连接套接字 
  42.     { 
  43.         printf("connect() failed! errno=%d\n",WSAGetLastError()); 
  44.         closesocket(sClient);//关闭套接字 
  45.         WSACleanup(); 
  46.         return
  47.     } 
  48.     printf("connect successfully!!\n"); 
  49.  
  50.     //向服务器发送数据 
  51.     char buf[BUF_SIZE]; 
  52.     ZeroMemory(buf,BUF_SIZE);//<==>memset(buf,0,BUF_SIZE); 
  53.     strcpy(buf,"Hello,Server!\n"); 
  54.     if (send(sClient,buf,strlen(buf),0) == SOCKET_ERROR) 
  55.     { 
  56.         printf("send() failed! erron=%d\n",WSAGetLastError()); 
  57.         closesocket(sClient); 
  58.         WSACleanup(); 
  59.         return
  60.     } 
  61.  
  62.     char bufRecv[BUF_SIZE]; 
  63.     memset(bufRecv,0,BUF_SIZE);//bufRecv需要置空,不然会出现多余的字符串输出 
  64.     RecvLine(sClient,bufRecv); 
  65.     printf("recv() from server:%s\n",bufRecv); 
  66.  
  67.     //退出 
  68.     closesocket(sClient); 
  69.     WSACleanup(); 
  70.     system("pause"); 
  71.     return
  72. void RecvLine(SOCKET s,char* buf) 
  73.     bool bLineEnd=false;//行结束 
  74.     int nDataLen=0;//数据长度 
  75.     int nReadLen=0;//读入字节长度 
  76.     while(!bLineEnd) 
  77.     { 
  78.         if ((nReadLen=recv(s,buf+nDataLen,1,0)) == SOCKET_ERROR)//每次接收一个字节 
  79.         { 
  80.             printf("recv() failed,errno=%d\n",WSAGetLastError()); 
  81.             closesocket(s); 
  82.             WSACleanup(); 
  83.             return
  84.         } 
  85.         if (nReadLen == 0) 
  86.         { 
  87.             printf("读数据失败"); 
  88.             break;//退出循环 
  89.         } 
  90.         if ('\n' == *(buf+nDataLen))//换行符 
  91.         { 
  92.             bLineEnd=true;//接收数据结束 
  93.         } 
  94.         else 
  95.         { 
  96.             nDataLen+=nReadLen;//增加数据长度 
  97.         } 
  98.     } 
  99. /*
  100. 1.gethostname()函数
  101. int gethostname(__out_bcount(namelen) char FAR * name,IN int namelen);//获取主机的名字
  102. 参数:name:用于保存主机名字的字符缓冲区地址
  103. 2.gethostbyname()函数
  104. struct hostent FAR * gethostbyname(__in const char FAR * name);//根据主机名称获取主机的网络地址
  105. struct  hostent {//表示主机的名称和网络地址
  106. char    FAR * h_name;           //* official name of host * 主机正式名称
  107. char    FAR * FAR * h_aliases;  /* alias list *主机别名
  108. short   h_addrtype;             /* host address type *地址类型
  109. short   h_length;               /* length of address *地址长度(用字节表示)
  110. char    FAR * FAR * h_addr_list; /* list of addresses *主机地址列表
  111. #define h_addr  h_addr_list[0]          /* address, for backward compat *
  112. };
  113. unsigned long addr=inet_addr("127.0.0.1");
  114. hostent host=gethostbyaddr((char*)&addr,sizeof(addr),2);
  115. */ 

结果图

 

本文转自:http://blog.csdn.net/ouyangshima/article/details/8967847

套接字的阻塞模式

WindowsSockets分别提供了套接字模式和套接字I/O模型,可以对一个套接字的行为进行控制。套接字模式用于当一个套接字被调用时,决定调用函数的阻塞行为。套接字模式有阻塞和非阻塞两种工作模式。套接字I/O模型描述了一个应用程序如何对套接字上的I/O进行管理。套接字和套接字I/O模型是两个不同的概念且他们之间是无关的。本章详细介绍套接字阻塞模式。第五章讲解
非阻塞模式,套接字
IO模型有(Select模型,WSAAsyncSelect模型,WSAEventSelect模型,重叠I/O模型,完成端口模型)他们分别在第六、七、八、九、十章讲解

阻塞模式

WindowsSockets在阻塞和非阻塞两种模式下执行I/O操作。在阻塞模式下,在I/O操作完成前,执行的操作函数将一直等候而不会立即返回,该函数所在的线程会阻塞在这里。相反,在非阻塞模式下,套接字函数会立即返回,而不管I/O是否完成,该函数所在的线程会继续运行。

在阻塞模式的套接字上,调用任何一个WindowsSockets API都会消耗不确定的等待时间。在调用recv()时,发生在内核中等待数据和复制数据的过程如下:

当调用recv()时,系统首先检查是否有准备好的数据。如果数据没有准备好,系统就处于等待状态。当数据准备好后,将数据从系统缓冲区复制到用户空间,然后该函数返回。在套接应用程序中,当调用recv()时,用户空间未必就已经存在数据,此时recv()函数就是会处在等待状态。

设置套接字的阻塞模式

在使用socket()WSASocket()创建套接字时,默认的套接字都是阻塞的。这意味着当调用WindowsSocketsAPI不能立即完成时,线程处于等待状态,直到操作完成。

并不是所有的WindowsSocketsAPI以阻塞套接字为参数调用都会发生阻塞。egbind(),listen()时,函数会立即返回。这里将可能阻塞套接字的WindowsSocketsAPI调用分为以下4

  • 输入操作:recv(),recvfrom(),WSARecv(),WSARecvfrom()。以阻塞套接字为参数调用这些函数接收数据,如果此时套接字缓冲区内没有数据可读,则调用线程在数据到来前一直睡眠。
  • 输出操作:send(),sendto(),WSASend(),WSASendto()。以阻塞套接字为参数调用这些哈思楠发送数据。如果套接字缓冲区没有可用空间,线程会一直睡眠,直到有空间。
  • 接收连接:accept(),WSAAcept()。以阻塞套接字为参数调用这些函数,将等待接受对方的连接请求,如果此时没有连接请求,线程就会进入睡眠状态。
  • 外出连接:connect(),WSAConnect()。对于TCP连接,客户端以阻塞套接字为参数,调用这些函数向服务器发起连接。该函数在收到服务器的应答前,不会返回。这就意味着TCP连接总会等待至少从客户端到服务器的一次往返的时间。

阻塞模式套接字的优势和不足

使用阻塞模式的套接字开发网络程序比较简单,容易实现。当希望能够理解发送和接收数据,且处理的套接字数量比较少的情况下,使用阻塞模式来开发网络程序比较合适。

阻塞模式套接字的不知表现为,在大量建立好的套接字线程之间进行通信时比较困难。当使用“生产者——消费者”模型开发网络程序时,为每个套接字都分别分配一个读线程,一个处理数据线程和一个用于同步的事件,无疑加大了系统的开销。阻塞模式套接字的最大的缺点是当希望同时处理大量套接字时,将无从下手,扩展性差。

客户端与服务器端相互问候

BlockServer

  1. // BlockServer.cpp : 定义控制台应用程序的入口点。 
  2.   
  3. #include <stdio.h> 
  4. #include <WinSock2.h> 
  5. #pragma comment(lib,"ws2_32.lib") 
  6. #define BUF_SIZE 64 
  7. SOCKET sServer;//服务器监听套接字 
  8. SOCKET sClient;//接收客户端套接字   
  9. void RecvLine(SOCKET s,char* buf);//读取一行数据 
  10. void main() 
  11.     char bufRecv[BUF_SIZE]; 
  12.     char bufSend[BUF_SIZE]; 
  13.     memset(bufSend,0,BUF_SIZE); 
  14.     memset(bufRecv,0,BUF_SIZE); 
  15.     sServer=INVALID_SOCKET; 
  16.     sClient=INVALID_SOCKET;  
  17.  
  18.     WSADATA wsd; 
  19.     if (WSAStartup(MAKEWORD(2,2),&wsd) != 0)//初始化Windows Sockets DLL 
  20.     { 
  21.         printf("WSAStartup() failed,errno=%d\n",GetLastError()); 
  22.         return
  23.     } 
  24.     if (LOBYTE(wsd.wVersion) != 2 || HIBYTE(wsd.wVersion) != 2)//确保WinSock DLL支持2.2 
  25.     { 
  26.         printf("can not find a usabe windwos sockets dll!"); 
  27.         WSACleanup(); 
  28.         return
  29.     } 
  30.     if ((sServer=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) == INVALID_SOCKET)//创建套接字 
  31.     { 
  32.         printf("socket() failed,errno=%d\n",WSAGetLastError()); 
  33.         WSACleanup(); 
  34.         return
  35.     } 
  36.     //服务器套接字地址  
  37.     SOCKADDR_IN addrServ; 
  38.     addrServ.sin_family=AF_INET; 
  39.     addrServ.sin_addr.S_un.S_addr=INADDR_ANY;//在程序中使用INADDR_ANY值作为网络地址,这意味着网络服务器提供者将使用合适的网络地址进行绑定。 
  40.     addrServ.sin_port=htons(5000); 
  41.     if (bind(sServer,(SOCKADDR*)&addrServ,sizeof(addrServ)) == SOCKET_ERROR)//绑定套接字 
  42.     { 
  43.         printf("bind() failed,errno=%d\n",WSAGetLastError()); 
  44.         closesocket(sServer); 
  45.         WSACleanup(); 
  46.         return
  47.     } 
  48.  
  49.     if ((listen(sServer,2)) == SOCKET_ERROR)//开始监听 
  50.     { 
  51.         closesocket(sServer); 
  52.         WSACleanup(); 
  53.         return
  54.     } 
  55.     printf("Server succeded!\nWaiting for new clients...\n");//等待客户端的连接 
  56.  
  57.     SOCKADDR_IN addrClient; 
  58.     int addrClientLen=sizeof(addrClient); 
  59.     if ((sClient=accept(sServer,(SOCKADDR*)&addrClient,&addrClientLen)) == INVALID_SOCKET)//接受客户端请求 
  60.     { 
  61.         printf("accept() failed,errno=%d\n",WSAGetLastError()); 
  62.         closesocket(sServer); 
  63.         WSACleanup(); 
  64.         return
  65.     }  
  66.     //显示客户端的IP和端口 
  67.     char* pClientIP=inet_ntoa(addrClient.sin_addr); 
  68.     u_short clientPort=ntohs(addrClient.sin_port); 
  69.     printf("accept a client[%s]:%d\n",pClientIP,clientPort); 
  70.  
  71.     RecvLine(sClient,bufRecv);//接收客户端数据 
  72.     printf("recv client info:%s\n",bufRecv); 
  73.  
  74.     strcpy(bufSend,"Hello,Client!\n"); 
  75.     if (send(sClient,bufSend,strlen(bufSend),0) == SOCKET_ERROR)//向客户端发送数据 
  76.     { 
  77.         printf("send() failed,errno=%d\n",WSAGetLastError()); 
  78.         closesocket(sClient); 
  79.         closesocket(sServer); 
  80.         WSACleanup(); 
  81.         return
  82.     } 
  83.     printf("server exiting...\n");//显示退出信息      
  84.     closesocket(sClient); 
  85.     closesocket(sServer); 
  86.     WSACleanup(); 
  87.     system("pause"); 
  88.     return
  89.  
  90. void RecvLine(SOCKET s,char* buf) 
  91.     BOOL bLineEnd=FALSE;//行结束 
  92.     int nReadLen=0;//读入字节数 
  93.     int nDataLen=0;//数据长度 
  94.     while(!bLineEnd) 
  95.     { 
  96.         if ((nReadLen=recv(s,buf+nDataLen,1,0)) == SOCKET_ERROR)//每次读取一个字节 
  97.         { 
  98.             printf("recv() failed,errno=%d\n",WSAGetLastError()); 
  99.             closesocket(s); 
  100.             closesocket(sServer); 
  101.             WSACleanup(); 
  102.             return
  103.         } 
  104.         if (nReadLen == 0) 
  105.         { 
  106.             printf("读数据失败"); 
  107.             break;//跳出循环 
  108.         } 
  109.         if ('\n' == *(buf+nDataLen))//换行符 
  110.         { 
  111.             bLineEnd=TRUE;//接收数据结束 
  112.         }  
  113.         else 
  114.         { 
  115.             nDataLen+=nReadLen;//增加数据长度 
  116.         } 
  117.     }  
  118. }  

BlockClient

  1. // BlockClient.cpp : 定义控制台应用程序的入口点。 
  2.   
  3. #include <WinSock2.h> 
  4. #include <stdio.h> 
  5. #pragma comment(lib,"ws2_32.lib") 
  6. #define BUF_SIZE 64 
  7. void RecvLine(SOCKET s,char* buf);//读取一行数据 
  8. void main() 
  9.     WSADATA wsd; 
  10.     if (WSAStartup(MAKEWORD(2,2),&wsd) != 0)//初始化套接字动态库 
  11.     { 
  12.         printf("WSAStartup() failed! erron=%d\n",GetLastError()); 
  13.         return
  14.     } 
  15.  
  16.     SOCKET sClient;//服务器套接字 
  17.     if ((sClient=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) == INVALID_SOCKET)//创建套接字 
  18.     { 
  19.         printf("socket() failed! errno=%d\n",WSAGetLastError()); 
  20.         WSACleanup();//释放套接字资源 
  21.         return
  22.     } 
  23.  
  24.     //获取主机的信息 
  25.     hostent* hostEntry; 
  26.     char hostname[BUF_SIZE]; 
  27.     gethostname(hostname,BUF_SIZE); 
  28.     if(!(hostEntry=gethostbyname(hostname))) 
  29.     { 
  30.         printf("gethostbyname() failed,errno=%d\n",GetLastError()); 
  31.         closesocket(sClient);//关闭套接字 
  32.         WSACleanup(); 
  33.         return
  34.     } 
  35.  
  36.    

抱歉!评论已关闭.