Windows网络编程(TCP流式套接字实验)

一、
实验环境

Windows10 vs2017 c/c++

二、实验内容

1.设计思路

  1. 基于流式套接字的时间同步服务器设计

要求使用流式套接字编程,实现时间同步服务器和客户端,该服务器能够接收客户端的查询请求,获取本地时间,并将结果发送回客户端,客户端将该时间显示出来,如图1所示。

(1) time()函数、ctime()函数为时间处理函数。

(2)客户的recv函数需要循环接收。

在这里插入图片描述

在这里插入图片描述

1.1服务器(时间服务器)

#include "pch.h"

#include <iostream>

#include <time.h>

#include "winsock2.h"

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

#define BUF_SZIE 64

int main()

{

    WSADATA         wsd;        //WSADATA变量

    SOCKET          sServer;    //服务器套接字

    SOCKET          sClient;    //客户端套接字

    SOCKADDR_IN     addrServ;;      //服务器地址

    char        buf[BUF_SZIE];  //接收数据缓冲区

    char            buf1[BUF_SZIE];  //发送

    int             retVal;         //返回值

    //初始化套结字动态库

    if (WSAStartup(MAKEWORD(2, 2), &wsd) !=
0)

    {

        printf("WSAStartupfailed!\n");

        return -1;

    }

    //创建套接字

    sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    if (INVALID_SOCKET == sServer)

    {

        printf("socketfailed!\n");

        WSACleanup();//释放套接字资源;

        return  -1;

    }

    //服务器套接字地址 

    addrServ.sin_family = AF_INET;

    addrServ.sin_port = htons(4999);

    addrServ.sin_addr.s_addr = INADDR_ANY;

    //绑定套接字

    retVal=bind(sServer(LPSOCKADDR)&addrServ,sizeof(SOCKADDR_IN));

    if (SOCKET_ERROR == retVal)

    {

        printf("bindfailed!\n");

        closesocket(sServer);    //关闭套接字

        WSACleanup();           //释放套接字资源;

        return -1;

    }

    //开始监听 

    retVal = listen(sServer, 3);

    if (SOCKET_ERROR == retVal)

    {

        printf("listenfailed!\n");

        closesocket(sServer);    //关闭套接字

        WSACleanup();           //释放套接字资源;

        return -1;

    }

        //接受客户端请求

        sockaddr_in addrClient;

        int addrClientlen = sizeof(addrClient);

        sClient=accept(sServer(sockaddr*)&addrClient,&addrClientlen);

        if (INVALID_SOCKET == sClient)

        {

            printf("acceptfailed!\n");

            closesocket(sServer);    //关闭套接字

            WSACleanup();           //释放套接字资源;

            return -1;

        }

        while (SOCKET_ERROR != retVal) {

            //接收客户端数据

            ZeroMemory(buf, BUF_SZIE);

            retVal = recv(sClient, buf, BUF_SZIE, 0);

            if (SOCKET_ERROR == retVal)

            {

                printf("recvfailed!\n");

                closesocket(sClient);    //关闭套接字

                closesocket(sServer);    //关闭套接字

                WSACleanup();           //释放套接字资源;

                return -1;

            }

            printf("%s\n", buf); //输出"MyTCP"

            //退出

            time_t t1;

            t1 = time(&t1);

            //      printf("%s\n", ctime(&t1));

            ZeroMemory(buf1, BUF_SZIE);

   ·         strcpy_s(buf1, ctime(&t1));

            retVal = send(sClient, buf1,strlen(buf1), 0);

            if (SOCKET_ERROR == retVal)

            {

                printf("sendfailed!\n");

                closesocket(sClient);    //关闭套接字

                WSACleanup();       //释放套接字资源

                return -1;

            }

        }

        closesocket(sClient);    //关闭套接字

    //}

    closesocket(sServer);    //关闭套接字

    WSACleanup();           //释放套接字资源;

    return 0;


}
1.2客户端(时间请求)

#include "pch.h"

#include <iostream>

#include <time.h>

#define  BUF_SZIE 64

#include "winsock2.h"

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

int main(int argc, char* argv[])

{

    WSADATA          wsd;         //WSADATA变量

    SOCKET           sHost;           //服务器套接字

    SOCKADDR_IN      servAddr;        //服务器地址

    char         buf[BUF_SZIE];   //发送数据缓冲区

    char         buf1[BUF_SZIE];  //接收数据缓冲区

    int              retVal;          //返回值

    //初始化套结字动态库

    if (WSAStartup(MAKEWORD(2, 2), &wsd) !=0)

    {

         printf("WSAStartupfailed!\n");

         return -1;

    }

    //创建套接字

    sHost= socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    if (INVALID_SOCKET == sHost)

    {

         printf("socketfailed!\n");

         WSACleanup();//释放套接字资源

         return  -1;

    }

    //设置服务器地址

    servAddr.sin_family= AF_INET;

    servAddr.sin_addr.s_addr = inet_addr("127.0.0.1");

    servAddr.sin_port= htons((short)4999);

    int nServAddlen = sizeof(servAddr);

    //连接服务器

   retVal=connect(sHost(LPSOCKADDR)&servAddr,sizeof(servAddr));

    if (SOCKET_ERROR == retVal)

    {

         printf("connectfailed!\n");

        closesocket(sHost);   //关闭套接字

         WSACleanup();    //释放套接字资源

         return -1;

    }

    while (SOCKET_ERROR != retVal) {

         //向服务器发送数据

         ZeroMemory(buf, BUF_SZIE);

         strcpy_s(buf,"timeplease!");

         retVal= send(sHost, buf, strlen(buf), 0);

         if (SOCKET_ERROR == retVal)

         {

             printf("sendfailed!\n");

             closesocket(sHost);   //关闭套接字

             WSACleanup();    //释放套接字资源

             return -1;

         }

         ZeroMemory(buf1, BUF_SZIE);

         retVal= recv(sHost, buf1, BUF_SZIE, 0);

         if (SOCKET_ERROR == retVal)

         {

             printf("recvfailed!\n");

             closesocket(sHost);   //关闭套接字

             WSACleanup();         //释放套接字资源;

             return -1;

         }

         printf("%s\n", buf1); //输出

 

         Sleep(1000);

    }

    closesocket(sHost);   //关闭套接字

    WSACleanup();    //释放套接字资源

    return 0;

}

2.基于流式套接字的服务器回射程序设计

编写一服务器程序和客户程序,要求客户每输入一行数据,服务器接收后加上echo:回送给客户程序,当客户输入“q”后退出。

(1) 为了提高流式套接字网络程序对流数据的接收能力,以循环服务器方式分别实现以下要求:

a. 如图2所示,客户端接收数据以recvline接收一行数据。

b. 如图3所示,服务器和客户端接收数据以recvn定长方式接收,其中长度由运行程序时指定。

c. 如图4所示,服务器和客户端接收数据均以recvvl变长方式接收,即将发送的消息设计为消息头和消息体,消息头包含消息体的长度。

在这里插入图片描述

服务器:

#include "pch.h"

#include <iostream>

#include <time.h>

#include "winsock2.h"

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

#define  BUF_SZIE 64

using namespace std;

int main()

{

    WSADATA          wsd;         //WSADATA变量

    SOCKET           sServer;     //服务器套接字

    SOCKET           sClient;     //客户端套接字

    SOCKADDR_IN      addrServ;;       //服务器地址

    char         buf[BUF_SZIE];   //接收数据缓冲区

    char            buf1[BUF_SZIE];  //发送

    int              retVal;          //返回值

    //初始化套结字动态库

    if (WSAStartup(MAKEWORD(2, 2), &wsd) !=0)

    {

         printf("WSAStartup failed!\n");

         return -1;

    }

    //创建套接字

    sServer
= socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    if (INVALID_SOCKET == sServer)

    {

         printf("socketfailed!\n");

         WSACleanup();//释放套接字资源;

         return  -1;

    }

    //服务器套接字地址 

    addrServ.sin_family= AF_INET;

    addrServ.sin_port= htons(4999);

    addrServ.sin_addr.s_addr = INADDR_ANY;

    //绑定套接字

    retVal=bind(sServer(LPSOCKADDR)&addrServ,sizeof(SOCKADDR_IN));

    if (SOCKET_ERROR == retVal)

    {

         printf("bindfailed!\n");

         closesocket(sServer); //关闭套接字

         WSACleanup();         //释放套接字资源;

         return -1;

    }

    //开始监听 

    retVal= listen(sServer, 3);

    if (SOCKET_ERROR == retVal)

    {

         printf("listenfailed!\n");

         closesocket(sServer); //关闭套接字

         WSACleanup();         //释放套接字资源;

         return -1;

    }

    //接受客户端请求

    sockaddr_in addrClient;

    int addrClientlen = sizeof(addrClient);

    sClient=accept(sServer(sockaddr*)&addrClient,&addrClientlen);

    if (INVALID_SOCKET == sClient)

    {

         printf("acceptfailed!\n");

         closesocket(sServer); //关闭套接字

         WSACleanup();         //释放套接字资源;

         return -1;

    }

    //显示客户端的IP和端口

    char *pClientIP = inet_ntoa(addrClient.sin_addr);

    u_short  clientPort = ntohs(addrClient.sin_port);

    cout<< "Accept aclient." << endl;

    cout<< "IP: " << pClientIP << endl;

    cout<< "Port: " << clientPort << endl;

    //接收客户端数据并回射 

    while (SOCKET_ERROR != retVal) {

         ZeroMemory(buf, BUF_SZIE);

         retVal= recv(sClient, buf, BUF_SZIE, 0);

         if (SOCKET_ERROR == retVal)

         {

             printf("recvfailed!\n");

             closesocket(sClient); //关闭套接字

             closesocket(sServer); //关闭套接字

             WSACleanup();         //释放套接字资源;

             return -1;

         }

        printf("echo:%s\n", buf);

         ZeroMemory(buf1, BUF_SZIE);

         strcpy_s(buf1,"echo:");

        strncat(buf1, buf, BUF_SZIE);

         retVal= send(sClient, buf1, strlen(buf1), 0);

         if (SOCKET_ERROR == retVal)

         {

             printf("sendfailed!\n");

             closesocket(sClient); //关闭套接字

             WSACleanup();    //释放套接字资源

             return -1;

         }

    }

    closesocket(sClient); //关闭套接字

    closesocket(sServer); //关闭套接字

    WSACleanup();         //释放套接字资源;

    return 0;

客户端:

#include "pch.h"

#include <iostream>

#include <time.h>

#include <stdio.h>

#define  BUF_SZIE 64

#include "winsock2.h"

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

using namespace std;

BOOL RecvLine(SOCKET s, char* buf); //读取一行数据

int recvn(SOCKET s, char * recvbuf, unsigned int fixedlen);

int recvvl(SOCKET s, char * recvbuf, unsigned int recvbuflen);

int main(int argc, char* argv[])

{

 

    WSADATA          wsd;         //WSADATA变量

    SOCKET           sHost;           //服务器套接字

    SOCKADDR_IN      servAddr;        //服务器地址

    char         buf[BUF_SZIE];   //发送数据缓冲区

    char         buf1[BUF_SZIE];  //接收数据缓冲区

    int              retVal;          //返回值

    //初始化套结字动态库

    if (WSAStartup(MAKEWORD(2, 2), &wsd) !=0)

    {

         printf("WSAStartupfailed!\n");

         return -1;

    }

    //创建套接字

    sHost= socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    if (INVALID_SOCKET == sHost)

    {

         printf("socketfailed!\n");

         WSACleanup();//释放套接字资源

         return  -1;

    }

    //准备连接服务器

    cout<< "Clientsucceeded!" << endl;

    cout<< "Be ready toconnect to server..." << endl;

    //设置服务器地址

    servAddr.sin_family= AF_INET;

    servAddr.sin_addr.s_addr = inet_addr("127.0.0.1");

    servAddr.sin_port= htons((short)4999);

    int nServAddlen = sizeof(servAddr);

    //连接服务器

    retVal=connect(sHost(LPSOCKADDR)&servAddr,sizeof(servAddr));

    if (SOCKET_ERROR == retVal)

    {

         printf("connect
failed!\n");

         closesocket(sHost);   //关闭套接字

         WSACleanup();    //释放套接字资源

         return -1;

    }

    //连接服务器成功

    cout<< "Connectsuccessfully!" << endl;

    while (SOCKET_ERROR != retVal) {

         //向服务器发送数据

         ZeroMemory(buf, BUF_SZIE);

         gets_s(buf);

         unsigned int len = strlen(buf);//获取读入字符串长度。

         buf[len]= '\n';//结尾增加换行符。

         buf[len+ 1] = '\0';//赋值新的结束符

         if (buf[0] == 'q' || buf[0] == 'Q') break;

         retVal= send(sHost, buf, strlen(buf), 0);

         if (SOCKET_ERROR == retVal)

         {

             printf("send failed!\n");

             closesocket(sHost);   //关闭套接字

             WSACleanup();    //释放套接字资源

             return -1;

         }

         //行接收

             if (!RecvLine(sHost,buf1))

             {

                 printf("recvfailed!\n");

                 closesocket(sHost);   //关闭套接字

                 WSACleanup();         //释放套接字资源;

                 return -1;

             }

             printf("%s\n", buf1);

    }

    closesocket(sHost);   //关闭套接字

    WSACleanup();    //释放套接字资源

    return 0;

}

BOOL RecvLine(SOCKET s, char* buf)

{

    BOOL retVal = TRUE;            //返回值

    BOOL bLineEnd = FALSE;     //行结束

    int      nReadLen = 0;         //读入字节数

    int      nDataLen = 0;         //数据长度

    ZeroMemory(buf, BUF_SZIE);

    while (!bLineEnd) //与客户端连接 没有换行

    {

         nReadLen= recv(s, buf + nDataLen, 1, 0);//每次接收一个字节

         //错误处理

         if (SOCKET_ERROR == nReadLen)

         {

             retVal= FALSE;  //读数据失败

             break;           //跳出循环                     

         }

         if (0 == nReadLen)//客户端关闭

         {

             retVal= FALSE;  //读数据失败

             break;           //跳出循环            

         }

         //读入数据

         if ('\n' == *(buf + nDataLen)) //换行符

         {

             bLineEnd= TRUE;          //接收数据结束

         }

         else {

             nDataLen+= nReadLen;     //增加数据长度

         }

    }

    return retVal;

}

在这里插入图片描述


服务器:(主要代码)

    //接收客户端数据并回射 

    while (SOCKET_ERROR != retVal) {

         ZeroMemory(buf, BUF_SZIE);

         int iResult =recvn(sClient, buf, 2);

         if (iResult != 2)

         {

             //如果变长消息在接收时没有返回足够的数据就返回0(连接关闭)或-1(发生错误)

             if (iResult == -1)

             {

                 printf("接收发生错误: %d\n",WSAGetLastError());

                 return -1;

             }

             else

             {

                 printf("连接关闭\n");

                 return 0;

             }

         }

        printf("ehco:%s\n", buf);

         ZeroMemory(buf1, BUF_SZIE);

         strcpy_s(buf1,"echo:");

         strncat(buf1,buf, BUF_SZIE);

         retVal= send(sClient, buf1, strlen(buf1), 0);

         if (SOCKET_ERROR == retVal)

         {

             printf("sendfailed!\n");

             closesocket(sClient); //关闭套接字

             WSACleanup();    //释放套接字资源

             return -1;

         }

    }

int recvn(SOCKET s, char * recvbuf, unsigned int fixedlen)

{

    int iResult;//存储单次recv操作的返回值

    int cnt;//用于统计相对于固定长度,剩余多少字节尚未接收

    cnt= fixedlen;

    while (cnt > 0)

    {

         iResult= recv(s, recvbuf, cnt, 0);

         if (iResult < 0)

         {

             //数据接收出现错误,返回失败

             printf("接收发生错误: %d\n", WSAGetLastError());

             return -1;

         }

         if (iResult == 0)

         {

             //对方关闭连接,返回已接收到的小于fixedlen的字节数

             printf("连接关闭\n");

             return fixedlen - cnt;

         }

         //接收缓存指针向后移动

         recvbuf += iResult;

         //更新cnt值

         cnt-= iResult;

    }

    return fixedlen;

}

在这里插入图片描述


服务器:

   //接收客户端数据并回射 

   while (SOCKET_ERROR != retVal) {

        ZeroMemory(buf, BUF_SZIE);

        retVal= recvvl(sClient, buf, BUF_SZIE);

        if (SOCKET_ERROR == retVal)

        {

            printf("recv failed!\n");

            closesocket(sClient); //关闭套接字

            closesocket(sServer); //关闭套接字

            WSACleanup();         //释放套接字资源;

            return -1;

        }

        printf("ehco:%s\n", buf);

        ZeroMemory(buf1, BUF_SZIE);

        strcpy_s(buf1,"echo:");

        strncat(buf1,buf, BUF_SZIE);



        unsigned int len = (unsigned int)strlen(buf1);

        len= htonl(len);

        retVal= send(sClient, (char*)&len, sizeof(unsigned int), 0);

        if (SOCKET_ERROR == retVal)

        {

            printf("send failed!\n");

            closesocket(sClient); //关闭套接字

            WSACleanup();    //释放套接字资源

            return -1;

        }



        retVal= send(sClient, buf1, strlen(buf1), 0);

        if (SOCKET_ERROR == retVal)

        {

            printf("sendfailed!\n");

            closesocket(sClient); //关闭套接字

            WSACleanup();    //释放套接字资源

            return -1;

        }

   }

int recvn(SOCKET s, char * recvbuf, unsigned int fixedlen)

{

   int iResult;//存储单次recv操作的返回值

   int cnt;//用于统计相对于固定长度,剩余多少字节尚未接收

   cnt= fixedlen;

   while (cnt > 0)

   {

        iResult= recv(s, recvbuf, cnt, 0);

        if (iResult < 0)

        {

            //数据接收出现错误,返回失败

            printf("接收发生错误: %d\n", WSAGetLastError());

            return -1;

        }

        if (iResult == 0)

        {

            //对方关闭连接,返回已接收到的小于fixedlen的字节数

            printf("连接关闭\n");

            return fixedlen - cnt;

        }

        //printf("接收到的字节数: %d\n", iResult);

        //接收缓存指针向后移动

        recvbuf += iResult;

        //更新cnt值

        cnt-= iResult;

   }

   return fixedlen;

}

int recvvl(SOCKET s, char * recvbuf, unsigned int recvbuflen)

{

   int iResult;//存储单次recv操作的返回值

   unsigned int reclen; //用于存储报文头部存储的长度信息

   //获取接收报文长度信息

   iResult= recvn(s, (char *)&reclen, sizeof(unsigned int));

   if (iResult != sizeof(unsigned int))

   {

        //如果长度字段在接收时没有返回一个整型数据就返回0(连接关闭)或-1(发生错误)

        if (iResult == -1)

        {

            printf("接收发生错误: %d\n", WSAGetLastError());

            return -1;

        }

        else

        {

            printf("连接关闭\n");

            return 0;

        }

   }

   //转换网络字节顺序到主机字节顺序

   reclen= ntohl(reclen);

   if (reclen > recvbuflen)

   {

        //如果recvbuf没有足够的空间存储变长消息,则接收该消息并丢弃,返回错误

        while (reclen > 0)

        {

            iResult= recvn(s, recvbuf, recvbuflen);

            if (iResult != recvbuflen)

            {

                //如果变长消息在接收时没有返回足够的数据就返回0(连接关闭)或-1(发生错误)

                if (iResult == -1)

                 {

                     printf("接收发生错误: %d\n", WSAGetLastError());

                     return -1;

                 }

                else

                {

                     printf("连接关闭\n");

                     return 0;

                }

            }

            reclen-= recvbuflen;

            //处理最后一段数据长度

            if (reclen < recvbuflen)

                recvbuflen = reclen;

        }

        printf("可变长度的消息超出预分配的接收缓存\r\n");

        return -1;

   }

   //接收可变长消息

   iResult= recvn(s, recvbuf, reclen);

   if (iResult != reclen)

   {

        //如果消息在接收时没有返回足够的数据就返回0(连接关闭)或-1(发生错误)

        if (iResult == -1)

        {

            printf("接收发生错误: %d\n", WSAGetLastError());

            return -1;

        }

        else

        {

            printf("连接关闭\n");

            return 0;

        }

   }

   return iResult;

}

并发服务器

并发服务器:

#include "pch.h"

#include <iostream>

#include <time.h>
#include "winsock2.h"
#pragma comment(lib, "ws2_32.lib")

#define  BUF_SZIE 64

using namespace std;


typedef struct my_file

{

 

    SOCKET clientSocket; //文件内部包含了一个SOCKET 用于和客户端进行通信

 

    sockaddr_in clientAddr; //用于保存客户端的socket地址

 

    int id; //文件块的序号

 

}F;

 DWORD WINAPI mywork(const LPVOID arg)

{

    char         buf[BUF_SZIE];   //接收数据缓冲区

    char            buf1[BUF_SZIE];  //发送

    int              retVal=0;             //返回值

    F *temp = (F*)arg;

    char *pClientIP =inet_ntoa(temp->clientAddr.sin_addr);

    u_short  clientPort = ntohs(temp->clientAddr.sin_port);

    cout<< "Accept a client." << endl;

    cout<< "IP: " << pClientIP << endl;

    cout<< "Port: " << clientPort << endl;

    //接收客户端数据并回射 

    

    while (SOCKET_ERROR != retVal) {

         ZeroMemory(buf, BUF_SZIE);

         retVal= recv(temp->clientSocket, buf, BUF_SZIE, 0);

         if (SOCKET_ERROR == retVal)

         {

             printf("recvfailed!\n");

             closesocket(temp->clientSocket);   //关闭套接字

             return -1;

         }

         printf("%s\n", buf);

 

         ZeroMemory(buf1, BUF_SZIE);

         strcpy_s(buf1,"echo:");

         strncat(buf1,buf, BUF_SZIE);

 

         retVal= send(temp->clientSocket, buf1, strlen(buf1), 0);

         if (SOCKET_ERROR == retVal)

         {

             printf("send failed!\n");

             closesocket(temp->clientSocket);   //关闭套接字

             return -1;

         }

    }

 

    closesocket(temp->clientSocket);   //关闭套接字

}

 

 

int main()

{

    WSADATA          wsd;         //WSADATA变量

    SOCKET           sServer;     //服务器套接字

    SOCKET           sClient;     //客户端套接字

    SOCKADDR_IN      addrServ;;       //服务器地址

    char         buf[BUF_SZIE];   //接收数据缓冲区

    char            buf1[BUF_SZIE];  //发送

    int              retVal;          //返回值

 

    //初始化套结字动态库

    if (WSAStartup(MAKEWORD(2, 2), &wsd) !=
0)

    {

         printf("WSAStartupfailed!\n");

         return -1;

    }

 

    //创建套接字

    sServer= socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    if (INVALID_SOCKET == sServer)

    {

         printf("socketfailed!\n");

         WSACleanup();//释放套接字资源;

         return  -1;

    }

 

    //服务器套接字地址 

    addrServ.sin_family= AF_INET;

    addrServ.sin_port= htons(4999);

    addrServ.sin_addr.s_addr = INADDR_ANY;

    //绑定套接字

    retVal= bind(sServer, (LPSOCKADDR)&addrServ, sizeof(SOCKADDR_IN));

    if (SOCKET_ERROR == retVal)

    {

         printf("bindfailed!\n");

         closesocket(sServer); //关闭套接字

         WSACleanup();         //释放套接字资源;

         return -1;

    }

 

    HANDLE hThread[20]; //获取句柄

 

    //开始监听 

    retVal= listen(sServer, 20);

    if (SOCKET_ERROR == retVal)

    {

         printf("listenfailed!\n");

         closesocket(sServer); //关闭套接字

         WSACleanup();         //释放套接字资源;

         return -1;

    }

    

    for (int i = 0; i < 20;i++) {

             F *temp = new F; //创建新的传输结构体         

             sockaddr_in clntAddr;     

             int nSize = sizeof(SOCKADDR);      

             SOCKET clientSock=accept(sServer(SOCKADDR*)&clntAddr,&nSize);     //temp数据成员赋值     

             temp->clientSocket= clientSock;       

             temp->id= i + 1;     

             temp->clientAddr= clntAddr;       //通过句柄创建子线程         

             hThread[i]= CreateThread(NULL, 0, &mywork, temp, 0, NULL);  

         }   

    WaitForMultipleObjects(20,hThread, TRUE, INFINITE);

 

    cout<< WSAGetLastError() << endl; //查看错误信息

    closesocket(sServer); //关闭套接字

    WSACleanup();         //释放套接字资源;

    cout<< "serverclose!" << endl;

    return 0;
}
  • 5
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值