网络编程作业——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函数来降低发送速度,此时,整个文件都能被服务端正确接受。
思考总结
注意初始化,有时候没有初始化会造成很大的问题
UDP发送端的发送频率如果过快,就会导致信息的淹没,接收方不能接收到完整信息
UDP是不可靠传输,所以需要设置超时时间,不然容易导致程序一直等待
如果UDP发送速度过快,会导致数据的淹没,从而出错。
总的来说,可靠的传输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*)¶, 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*)¶, 0, NULL); if (hThread == NULL) { cout << "Create Thread failed!" << endl; break; } CloseHandle(hThread); } closesocket(ServerSocket);// closesocket(ClientSocket); WSACleanup(); system("pause"); return 0;}
ss
- 网络编程作业——UDP传输
- 网络编程作业——UDP传输
- 黑马程序员——网络编程之UDP传输
- Unix网络编程—传输层:TCP和UDP
- 网络编程—UDP协议传输接受与发送数据
- 网络编程之UDP传输
- 黑马程序员_java网络编程——UDP传输和TCP传输
- Java基础—网络编程【OSI/RM TCP/IP】【网络通信三要素】【UDP传输 & TCP传输】【DNS域名解析】
- Java基础—网络编程【OSI/RM TCP/IP】【网络通信三要素】【UDP传输 & TCP传输】【DNS域名解析】
- Java基础—网络编程【OSI/RM TCP/IP】【网络通信三要素】【UDP传输 & TCP传输】【DNS域名解析】
- 黑马程序员——java网络编程中的传输协议:UDP和TCP
- 黑马程序员 【】java学习之路——网络编程之UDP传输简析
- 黑马程序员 【】java学习之路——网络编程 UDP 键盘录入传输
- 黑马程序员:网络编程之UDP传输
- 黑马程序员-网络编程 udp传输
- 黑马程序员:网络编程之UDP传输
- java网络编程--udp传输示例
- UDP传输----java网络编程(1)
- 【code force】模拟 746C
- 零行代码为 App 添加异常加载占位图
- Linux-常见环境变量及其作用
- 使用非Android系统的其他字体
- 服务器Reactor架构浅析
- 网络编程作业——UDP传输
- excel打开csv文件乱码问题
- 判断一个数是否是2的N次方
- 网络编程作业——UDP传输
- Poj_3278 Catch That Cow(BFS)
- xml中id带+与不带+的区别
- 【数据库开发】MySQL修改root密码
- Laravel之请求(转载)
- svn: OPTIONS request failed on