网络编程作业——UDP传输

来源:互联网 发布:socket java 长连接 编辑:程序博客网 时间:2024/06/10 13:06

UDP 编程

  • UDP 编程
    • 要求
      • 实验一
      • 实验二
    • 分析
      • 实验一
      • 实验二
    • 实验结果
      • 实验一
        • 服务端开启的时候
        • 服务端关闭的时候
      • 实验二
        • 短文件传输
        • 长文件传输
    • 思考总结
    • 代码
      • 实验一
        • Client
        • Server
      • 实验二
        • Client
        • Server

要求

实验一

  • 客户端和服务端交互,客户端发送信息
  • 服务端显示信息来源并且将接收到的信息回传给发送方
  • 服务端使用多线程实现并发
  • 观察在服务端启动或者不启动时,客户端运行情况

实验二

  • 客户端向服务端发送文件名
  • 客户端想服务端传输文件内容
  • 双方关闭套接字
  • 注意收发速度对文件的传输结果的影响

分析

实验一

  • 首先服务端启动
    和tcp的服务端启动类似,不过不需要listen,
    只要创建socket并且绑定端口就行。

  • 然后就是recvfrom等待客户端连接

  • 一旦客户端发送数据过来了,就创建新线程,在新线程中创建一个新的socket,绑定一个新的未被占用的端口,然后给客户端返回信息。

    //创建一个新的socket    newsocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);    if (newsocket == INVALID_SOCKET)    {        cout << "Create Transfer socket failed with error: " << WSAGetLastError() << endl;        return -1;    }    sockaddr_in newaddr;    newaddr.sin_family = AF_INET;    newaddr.sin_addr.s_addr = inet_addr(IP_ADDR);    newaddr.sin_addr.S_un.S_addr = INADDR_ANY;    memset(newaddr.sin_zero, 0x00, 8);    int notfirst = 0;    int newaddr_len = sizeof(newaddr);    //bind socket,一个新的端口    iResult = bind(newsocket, (struct sockaddr *)&newaddr, newaddr_len);    if (iResult != 0)    {        cout << "Bind socket failed: " << WSAGetLastError() << endl;        closesocket(newsocket);        return -1;    }
  • 采用循环交互,只要客户端不发送“End”,双方的通信就不会结束

  • UDP是无连接的,所以无论在服务端是否开启的情况下,客户端都能进行数据发送,因为客户根本不在乎服务端是否接受。
    在服务端没有开启的情况下,客户端不能收到服务端的返回,所以会超时错误。

实验二

  • 整个交互的过程是客户端发送文件名,服务端接受到之后,开一个新线程,创建一个新的套接字,绑定一个新的端口来进行余下的文件传输,通过给客户端返回信息来通知新的端口信息。然后,客户端发送文件长度,然后是文件内容,文件发送和接受都是循环的,直到文件传输完全成功

  • 设置了超时时间,在文件传输过程中,一旦发生问题,服务端接收不到后续信息,超时之后自动退出

//设置超时时间    int nTimeOver = 10000;    setsockopt(TransSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&nTimeOver, sizeof(nTimeOver));
  • 客户端也设置了超时时间,如果在发送文件结束之后,如果超时时间内没有收到服务端的确认信息就自动退出
int nTimeover = 1000;        setsockopt(ClientSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&nTimeover, sizeof(nTimeover));
  • 关于传输时间控制,使用的是sleep()函数,在前后两次发送之间调用sleep()来降低传输速度,从而可以使得UDP报文的数据不会因为传输速度太快而淹没。
Sleep(100);

实验结果

实验一

服务端开启的时候

  • 客户端参数设置

  • 可以多次发送数据

    可以多次发送数据

  • 可以接受多个客户端的同时发送数据

服务端关闭的时候

当服务器被关闭的时候

客户端可以正常发送数据,因为UDP不需要建立连接
但是客户端是不可能接收到服务端的返回信息所以会显示错误代码10060,就是在超时时间内接受不到,停止阻塞。

实验二

短文件传输

  • 客户端参数设置

PS:
2.txt大小为94643个字节

  • 文件传输

    此时文件长度还不是很长,每次发送都能被服务端接收到,而且返回信息也是成功。

长文件传输

  • 客户端参数设置

PS:
3.pdf大小为183662个字节

  • 文件传输

可以从运行结果看出来,当文件过大的时候,容易有一部分的数据不能被接收,非常容易造成内容的丢失。
此时服务端会等到超时时间到了之后自动停止阻塞

  • 修改——控制发送速度
    在每次发送,开始下一次发送之前,调用sleep函数来降低发送速度,此时,整个文件都能被服务端正确接受。

思考总结

  1. 注意初始化,有时候没有初始化会造成很大的问题

  2. UDP发送端的发送频率如果过快,就会导致信息的淹没,接收方不能接收到完整信息

  3. UDP是不可靠传输,所以需要设置超时时间,不然容易导致程序一直等待

  4. 如果UDP发送速度过快,会导致数据的淹没,从而出错。

  5. 总的来说,可靠的传输TCP虽然设置稍微复杂,但是稳定程度,可靠程度高很多,编程的时候也不容易出现特别奇怪的问题,不可靠传输UDP,虽然看上去简单一些,但是实际编程中会遇到各种乱七八糟的问题,也更加难以调试,难以发现错误。

代码

实验一

Client

#define _WINSOCK_DEPRECATED_NO_WARNINGS#include <stdio.h>#include <WinSock2.h>#include <iostream>#pragma comment (lib,"ws2_32.lib")#define MAX_LEN 100000using namespace std;int main(int argc, char * argv[]){    WSADATA ws;    int iResult;    SOCKET ClientSocket = INVALID_SOCKET;    struct sockaddr_in Server_addr;    int Server_len;    //检查参数个数    if (argc != 3)    {        cout << "Need enter target IP and port !" << endl;        return -1;    }    int PORT = atoi(argv[2]);    //初始化 socket    iResult = WSAStartup(MAKEWORD(2, 2), &ws);    if (iResult != 0)    {        cout << "Initiate failed with error: " << GetLastError() << endl;        WSACleanup();        return -1;    }    //创建 socket    ClientSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);    if (ClientSocket == INVALID_SOCKET)    {        cout << "Create Client socket failed with error: " << WSAGetLastError() << endl;        WSACleanup();        return -1;    }    Server_addr.sin_family = AF_INET;    Server_addr.sin_addr.s_addr = inet_addr(argv[1]);    Server_addr.sin_port = htons(PORT);    memset(Server_addr.sin_zero, 0x00, 8);    Server_len = sizeof(Server_addr);    char data[MAX_LEN];    cout << "########################################### Interactive Mode ############################################" << endl;    while (TRUE)    {        cout << "Please enter the data to send! Enter \"End\" to close the Interactive mode" << endl;        cin >> data;        cout << endl;        int len = strlen(data);        iResult = sendto(ClientSocket, data, strlen(data), 0, (sockaddr *)&Server_addr, Server_len);        if (iResult != strlen(data) && iResult != MAX_LEN)        {            cout << "Sending failed with error :" << WSAGetLastError() << endl;            cout << "Client exit." << endl;            closesocket(ClientSocket);            WSACleanup();            return -1;        }        else if (iResult == MAX_LEN)        {            cout << "Sending data buffer is already full!\n " << WSAGetLastError() << endl;        }        int Recv_Server_addr_len = 0;        char recvdata[MAX_LEN];        sockaddr_in confire_addr;        int nTimeover = 1000;        setsockopt(ClientSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&nTimeover, sizeof(nTimeover));        iResult = recvfrom(ClientSocket, recvdata, MAX_LEN, 0, (sockaddr *)&Server_addr, &Server_len);        if (iResult > 0)        {            recvdata[iResult] = '\0';            cout << "Receive data from Server ( " << inet_ntoa(Server_addr.sin_addr) << " : " << Server_addr.sin_port << " ) successfully!" << endl;            cout << "Receive Data:" << endl;            cout << recvdata << "\n\n" << endl;            if (strcmp(recvdata, "End") == 0)            {                break;            }        }        else if (iResult == 0)        {            cout << "Connection closed!\n" << endl;        }        else        {            cout << "Receive failed with error: " << WSAGetLastError() << endl;        }    }    cout << "Client exit." << endl;    cout << "########################################### Interactive End ############################################\n" << endl;    closesocket(ClientSocket);    WSACleanup();    system("pause");    return 0;}

Server

#define _WINSOCK_DEPRECATED_NO_WARNINGS#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#include <WinSock2.h>#include <WS2tcpip.h>#include <iostream>#include <stdlib.h>#include <stdint.h>#include <fstream>using namespace std;#pragma comment (lib,"ws2_32.lib")#define PORT 4000#define IP_ADDR "0.0.0.0"#define  MAX_LEN 100000struct inform{    SOCKET server;    sockaddr_in remote;    int remote_len;    char *data;};int newport = 5000;//多线程函数DWORD WINAPI ClientThread(LPVOID lpparameter){    int iResult = 0;    char data[MAX_LEN];    struct inform para = *(struct inform* ) lpparameter;    SOCKET serSocket = (SOCKET)para.server;    sockaddr_in remotesock = para.remote;    int remotesock_len = para.remote_len;    strcpy(data, para.data);    SOCKET newsocket;    int newsocket_len = sizeof(newsocket);    sockaddr_in interactive;    int interactive_len = sizeof(interactive);    //创建一个新的socket    newsocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);    if (newsocket == INVALID_SOCKET)    {        cout << "Create Transfer socket failed with error: " << WSAGetLastError() << endl;        return -1;    }    sockaddr_in newaddr;    newaddr.sin_family = AF_INET;    newaddr.sin_addr.s_addr = inet_addr(IP_ADDR);    newaddr.sin_port = newport++;    newaddr.sin_addr.S_un.S_addr = INADDR_ANY;    memset(newaddr.sin_zero, 0x00, 8);    int notfirst = 0;    int newaddr_len = sizeof(newaddr);    //bind socket,一个新的端口    iResult = bind(newsocket, (struct sockaddr *)&newaddr, newaddr_len);    if (iResult != 0)    {        cout << "Bind socket failed: " << WSAGetLastError() << endl;        closesocket(newsocket);        return -1;    }    cout << "########################################### Interactive Mode ############################################\n" << endl;    while (true)    {        if (notfirst)        {            iResult = recvfrom(newsocket, data, MAX_LEN, 0, (struct sockaddr *)&interactive, &interactive_len);            if (iResult == SOCKET_ERROR || iResult == 0)            {                cout << "Receive data failed with error " << WSAGetLastError() << endl;                closesocket(newsocket);                return -1;            }            data[iResult] = '\0';        }        notfirst = 1;        cout << "Receive from ( " << inet_ntoa(remotesock.sin_addr) << " :" << remotesock.sin_port << " )" << endl;        cout << "Data: " << endl;        cout << data << endl;        cout << "Return Message\n" << endl;        iResult = sendto(newsocket, data, strlen(data), 0, (sockaddr *)&remotesock, remotesock_len);        if (iResult == SOCKET_ERROR || iResult == 0)        {            cout << "Return message failed with error " << WSAGetLastError() << endl;            closesocket(newsocket);            return -1;        }        if (strcmp(data, "End") == 0)        {            break;        }    }    cout << "Return message to " << inet_ntoa(remotesock.sin_addr)<<" finished\n" << endl;    cout << "################################################### Interactive End ###################################################\n\n" << endl;    closesocket(newsocket);    return 0;}int main(int argc, char * argv[]){    WSADATA ws;    SOCKET ServerSocket = INVALID_SOCKET, ClientSocket = INVALID_SOCKET;    sockaddr_in LocalAddr,remote_addr;    int iResult = 0;    int Addrlen = 0;    HANDLE hThread = NULL;    //Initiate     iResult = WSAStartup(MAKEWORD(2, 2), &ws);    if (iResult != 0)    {        cout << "Initiate failed with error: " << WSAGetLastError() << endl;        return -1;    }    //create socket    ServerSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);    if (ServerSocket == INVALID_SOCKET)    {        cout << "create socket failed with error: " << WSAGetLastError() << endl;        WSACleanup();        return -1;    }    LocalAddr.sin_family = AF_INET;    LocalAddr.sin_addr.s_addr = inet_addr(IP_ADDR);    LocalAddr.sin_port = htons(PORT);    LocalAddr.sin_addr.S_un.S_addr = INADDR_ANY;    memset(LocalAddr.sin_zero, 0x00, 8);    //bind socket    iResult = bind(ServerSocket, (struct sockaddr *)&LocalAddr, sizeof(LocalAddr));    if (iResult != 0)    {        cout << "Bind socket failed: " << WSAGetLastError() << endl;        closesocket(ServerSocket);        WSACleanup();        return -1;    }    char Recvbuf[MAX_LEN];    int remote_len = sizeof(remote_addr);    cout << "UDP server started up!\n" << endl;    while (TRUE)    {        iResult = recvfrom(ServerSocket, Recvbuf, MAX_LEN, 0, (struct sockaddr *)&remote_addr, &remote_len);        if (iResult == SOCKET_ERROR || iResult == 0)        {            cout << "Receive data failed with error " << WSAGetLastError() << endl;            //每次如果出现任何错误,continue会回到这里,因为这个时候客户端已经关闭,就可以统一的closesocket关闭连接同时返回            return -1;        }        Recvbuf[iResult] = '\0';        struct inform para;        para.server = ServerSocket;        para.remote = remote_addr;        para.remote_len = remote_len;        para.data = Recvbuf;        hThread = CreateThread(NULL, 0, ClientThread, (LPVOID*)&para, 0, NULL);        if (hThread == NULL)        {            cout << "Create Thread failed!" << endl;            break;        }        CloseHandle(hThread);    }    closesocket(ServerSocket);    WSACleanup();    system("pause");    return 0;}

实验二

Client

#define _WINSOCK_DEPRECATED_NO_WARNINGS#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#include <WinSock2.h>#include <WS2tcpip.h>#include <iostream>#include <stdlib.h>#include <stdint.h>#include <fstream>#include<io.h>#include <stdint.h>using namespace std;#pragma comment (lib,"ws2_32.lib")using namespace std;//缓存区长度#define  MAX_LEN 10000int __cdecl main(int argc, char* argv[]){    WSADATA ws;    SOCKET ClientSocket = INVALID_SOCKET;    struct sockaddr_in Server_addr,Confirm_addr;    int iResult = 0;    int Addrlen = 0;    HANDLE hThread = NULL;    char Recvbuffer[MAX_LEN + 2];    //检查参数个数    if (argc != 4)    {        cout << "Need enter target IP, port and the file name to transmit !" << endl;        return -1;    }    int PORT = atoi(argv[2]);    //初始化 socket    iResult = WSAStartup(MAKEWORD(2, 2), &ws);    if (iResult != 0)    {        cout << "Initiate failed with error: " << GetLastError() << endl;        return -1;    }    //创建 socket    ClientSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);    if (ClientSocket == INVALID_SOCKET)    {        cout << "Create Client socket failed with error: " << WSAGetLastError() << endl;        WSACleanup();        return -1;    }    Server_addr.sin_family = AF_INET;    Server_addr.sin_addr.s_addr = inet_addr(argv[1]);    Server_addr.sin_port = htons(PORT);    memset(Server_addr.sin_zero, 0x00, 8);    int Server_addr_len = sizeof(Server_addr);    char filebuf[MAX_LEN + 1];        //文件内容存储数组    //确定文件的大小    int len;    FILE* fp;    if (fp = fopen(argv[3], "r"))    {        fseek(fp, 0, SEEK_END);        printf("%ld\n", ftell(fp));        len = ftell(fp);        fclose(fp);    }    else    {        cout << "Error to get the size of file\n" << endl;        cout << "Client exit." << endl;        closesocket(ClientSocket);        WSACleanup();        return -1;    }    //设置超时时间    int nTimeOver = 10000;    setsockopt(ClientSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&nTimeOver, sizeof(nTimeOver));    //传输文件,先传输文件名,再传输文件长度,最后传输文件内容    cout << "########################################## File Information ##########################################" << endl;        int len3 = strlen(argv[3]);        //对文件名传输进行处理        char filename[MAX_PATH];        int i = 0;        for (i = 0; i < len3; i++)        {            filename[i] = argv[3][i];        }        filename[i++] = '#';        filename[i++] = '\0';        //传输文件名                iResult = sendto(ClientSocket, filename, strlen(filename), 0,(sockaddr*)&Server_addr,Server_addr_len);        if (iResult != strlen(filename) || iResult >= MAX_PATH)        {            cout << "Sending filename with error :" << WSAGetLastError() << endl;            cout << "Client exit." << endl;            closesocket(ClientSocket);            WSACleanup();            return -1;        }        cout << "Sending filename to ( " << inet_ntoa(Server_addr.sin_addr) << " : " << Server_addr.sin_port<<" ) " << endl;        //获取传输地址信息,端口        sockaddr_in trans_addr;        int trans_addr_len=sizeof(trans_addr);        iResult = recvfrom(ClientSocket, Recvbuffer, MAX_LEN, 0, (struct sockaddr *)&trans_addr, &trans_addr_len);        Recvbuffer[iResult] = '\0';        if (strcmp(Recvbuffer,"Ready to receive file!")!=0)        {            cout << "Error: " << WSAGetLastError() << endl;            cout << "Unable to assure the port to send file!\n" << endl;            closesocket(ClientSocket);            WSACleanup();            system("pause");            return -1;            //break;        }        else        {            cout << "File transfer to ( " << inet_ntoa(trans_addr.sin_addr) << " : " << trans_addr.sin_port <<" ) "<< endl;        }        //以二进制文件形式读取文件        ifstream sourcefile(argv[3], ios::in | ios::binary);        int filelen = len;        int filelen_net = htonl(filelen);        //传输内容长度        cout << "Sending the length of file : " << filelen << "\n" << endl;        iResult = sendto(ClientSocket, (char*)&filelen_net, 4, 0,(sockaddr*)&trans_addr,trans_addr_len);        if (iResult == SOCKET_ERROR)        {            cout << "Send file length failed with error " << WSAGetLastError() << endl;            closesocket(ClientSocket);            WSACleanup();            system("pause");            return -1;        }        //传输文件内容        cout << "########################################## Sending file ##########################################" << endl;        int left = filelen;        int mode = 0;        while (left > 0)        {            if (left > MAX_LEN)            {                mode = MAX_LEN;            }            else            {                mode = left;            }            sourcefile.read(filebuf, mode);            iResult = sendto(ClientSocket, filebuf, mode, 0, (sockaddr*)&trans_addr, trans_addr_len);            if (iResult == SOCKET_ERROR)            {                cout << "Send file content failed with error " << WSAGetLastError() << "\n" << endl;                break;            }            left -= mode;            cout << "Sending Bytes: " << mode << endl;            Sleep(100);        }        sourcefile.close();        if (left != 0)        {            cout << "Send file content failed with error " << WSAGetLastError() << "\n" << endl;            cout << "Client Exit..." << endl;            closesocket(ClientSocket);            WSACleanup();            system("pause");            return -1;        }        //判断来自客户端的返回信息        cout << "########################################## Confirm information ##########################################\n" << endl;        int Confirm_addr_len = sizeof(Confirm_addr);        iResult = recvfrom(ClientSocket, Recvbuffer, MAX_LEN, 0, (sockaddr *)&Confirm_addr, &Confirm_addr_len);        Recvbuffer[iResult] = '\0';        if (iResult > 0)        {            cout << "Receive information from server ( " << inet_ntoa(Confirm_addr.sin_addr)<<" : "<<Confirm_addr.sin_port<<" )\n" << endl;        }        cout << "########################################## Exit ##########################################" << endl;    closesocket(ClientSocket);    WSACleanup();    system("pause");    return 0;}

Server

#define _WINSOCK_DEPRECATED_NO_WARNINGS#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#include <WinSock2.h>#include <WS2tcpip.h>#include <iostream>#include <stdlib.h>#include <stdint.h>#include <fstream>using namespace std;#pragma comment (lib,"ws2_32.lib")#define PORT 4000#define IP_ADDR "0.0.0.0"#define  MAX_LEN 10000//自己定义的结构体,用于多线程传参struct inform{    SOCKET server;    sockaddr_in remote;    int remote_len;    char *data;};int newport = 4500;//多线程函数DWORD WINAPI ClientThread(LPVOID lpparameter){    struct inform para = *(struct inform *)lpparameter;    int iResult = 0;    char RecvBuffer[MAX_LEN];    //传参处理    SOCKET ConnectSocket = (SOCKET)para.server;    SOCKET TransSocket = INVALID_SOCKET;    sockaddr_in remote = para.remote;    int remote_len = para.remote_len;    char *data = para.data;    int filelength = 0;    char filename[MAX_PATH] = { 0 };    //对于传输的文件名进行处理    int cnt = 0;    while (data[cnt] != '#')    {        filename[cnt] = data[cnt];        cnt++;    }    filename[cnt] = '\0';    char connectmessage[] = "Ready to receive file!";    //创建一个新的socket    TransSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);    if (TransSocket == INVALID_SOCKET)    {        cout << "Create Transfer socket failed with error: " << WSAGetLastError() << endl;        return -1;    }    sockaddr_in newaddr;    newaddr.sin_family = AF_INET;    newaddr.sin_addr.s_addr = inet_addr(IP_ADDR);    newaddr.sin_addr.S_un.S_addr = INADDR_ANY;    memset(newaddr.sin_zero, 0x00, 8);    int newaddr_len = sizeof(newaddr);    //bind socket,一个新的端口    iResult = bind(TransSocket, (struct sockaddr *)&newaddr, newaddr_len);    if (iResult != 0)    {        cout << "Bind socket failed: " << WSAGetLastError() << endl;        closesocket(TransSocket);        return -1;    }    //设置超时时间    int nTimeOver = 10000;    setsockopt(TransSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&nTimeOver, sizeof(nTimeOver));    //用新的socket给client发送确认信息,后续传输用新的socket    //如果确认失败,退出    iResult = sendto(TransSocket, connectmessage, strlen(connectmessage), 0, (sockaddr*)&remote, remote_len);    if (iResult == SOCKET_ERROR)    {        cout << "Return confirm message with error " << WSAGetLastError() << endl;        cout << "Unable for client to transfer with a new socket." << endl;        cout << "Exit!\n" << endl;        closesocket(TransSocket);        return -1;    }    cout << "Ready to receive file!\n" << endl;    //接收文件长度数据    int len_tran = 0;    iResult = recvfrom(TransSocket, (char*)&len_tran, 4, 0, (sockaddr*)&remote, &remote_len);    if (iResult != 4)    {        if (iResult == -1)        {            cout << "Receive failed with error " << WSAGetLastError() << endl;            closesocket(TransSocket);            return -1;        }        else        {            cout << "Length data is not complete. Connection closed\n" << endl;            closesocket(TransSocket);            return -1;        }    }    int recvlen = ntohl(len_tran);    cout << "The length of file to receive is " << recvlen << "\n" << endl;    //创建文件    ofstream rec_file;    rec_file.open(filename, ios::binary);    int left = recvlen;    int mode = 0;    while (left > 0)    {        if (left >= MAX_LEN)        {            mode = MAX_LEN;        }        else        {            mode = left;        }        iResult = recvfrom(TransSocket, RecvBuffer, mode, 0, (sockaddr*)&remote, &remote_len);;        if (iResult == -1)        {            cout << "Receive failed with error " << WSAGetLastError() << endl;            break;        }        else if (iResult == 0)        {            cout << "Receive data stopped. There " << left << " bytes unreceived" << endl;            break;        }        else        {            rec_file.write(RecvBuffer, mode);                        cout << "Receive data : " << iResult << " bytes" << endl;        }        left -= mode;        cout << " There " << left << " bytes unreceived\n" << endl;    }    if (left == 0)    {        cout << "Receive all the data\n" << endl;        char returnmessage[] = "OK\0";        iResult = sendto(TransSocket, returnmessage, strlen(returnmessage), 0, (sockaddr*)&remote, remote_len);        if (iResult == SOCKET_ERROR)        {            cout << "Return confirm message with error " << WSAGetLastError() << endl;            cout << "End!\n" << endl;            closesocket(TransSocket);            return -1;        }        else        {            cout << "Return success!\n" << endl;            cout << "######################################################## End ########################################################\n\n" << endl;        }    }    else    {        cout << "File transfer is too vulnerable!\n" << endl;        cout << "End!\n" << endl;        closesocket(TransSocket);        return -1;    }    rec_file.close();    closesocket(TransSocket);    return 0;}int main(int argc, char * argv[]){    WSADATA ws;    SOCKET ServerSocket = INVALID_SOCKET, ClientSocket = INVALID_SOCKET;    sockaddr_in LocalAddr, ClientAddr;    int iResult = 0;    int Addrlen = 0;    HANDLE hThread = NULL;    //Initiate     iResult = WSAStartup(MAKEWORD(2, 2), &ws);    if (iResult != 0)    {        cout << "Initiate failed with error: " << WSAGetLastError() << endl;        return -1;    }    //create socket    ServerSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);    if (ServerSocket == INVALID_SOCKET)    {        cout << "create socket failed with error: " << WSAGetLastError() << endl;        WSACleanup();        return -1;    }    LocalAddr.sin_family = AF_INET;    LocalAddr.sin_addr.s_addr = inet_addr(IP_ADDR);    LocalAddr.sin_port = htons(PORT);    LocalAddr.sin_addr.S_un.S_addr = INADDR_ANY;    memset(LocalAddr.sin_zero, 0x00, 8);    //bind socket    iResult = bind(ServerSocket, (struct sockaddr *)&LocalAddr, sizeof(LocalAddr));    if (iResult != 0)    {        cout << "Bind socket failed: " << WSAGetLastError() << endl;        closesocket(ServerSocket);        WSACleanup();        return -1;    }    cout << "UDP Server is already setup!\n" << endl;    char Recvbuf[MAX_LEN + 1];    int ClientAddr_len;    sockaddr_in remote_addr;    int remote_len = sizeof(remote_addr);    while (TRUE)    {        iResult = recvfrom(ServerSocket, Recvbuf, MAX_LEN, 0, (struct sockaddr *)&remote_addr, &remote_len);        if (iResult == SOCKET_ERROR || iResult == 0)        {            cout << "Receive data failed with error " << WSAGetLastError() << endl;            //每次如果出现任何错误,continue会回到这里,因为这个时候客户端已经关闭,就可以统一的closesocket关闭连接同时返回            continue;        }        Recvbuf[iResult] = '\0';        struct inform para;        para.server = ServerSocket;        para.remote = remote_addr;        para.remote_len = remote_len;        para.data = Recvbuf;        cout << "################################################ Connect with client ##################################################" << endl;        cout << "IP address: " << inet_ntoa(remote_addr.sin_addr) << "  port: " << remote_addr.sin_port << endl;        hThread = CreateThread(NULL, 0, ClientThread, (LPVOID*)&para, 0, NULL);        if (hThread == NULL)        {            cout << "Create Thread failed!" << endl;            break;        }        CloseHandle(hThread);    }    closesocket(ServerSocket);//    closesocket(ClientSocket);    WSACleanup();    system("pause");    return 0;}

ss

0 0