UDP并发服务器(客户端多次交互)
程序采用多线程实现
对于UDP并发,如果客户单次交互,那么为每一个客户新建套接字,响应后关闭套接字即可。
但如果是多次交互,服务器不仅需要为每个客户建立套接字,还要为客户绑定新的端口,使客户在新的端口与服务器交互,这就要求客户需要直到服务器绑定的新端口信息。
在下述程序中,客户首先向服务器发送一字节的激活包,服务器收到激活包后为客户绑定新的套接字,并回射ECHO:<激活包内容>,客户从这个回射中得知(通过recvfrom的参数)新的端口号,在新端口上同服务器进行交互。
话不多说,上代码。结构很烂。运行时需要输入IP,程序从argv参数获得IP。为了方标调试,也可以在程序中赋IP。程序里都写了,只不过注释掉了,改一改就好。
//客户
#pragma comment(lib,"ws2_32.lib")
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <winsock2.h>
#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fstream>
#include <iostream>
#define SER_PORT 2333
#define BUFF_LEN 1100
using namespace std;
int startUp() {
WORD wVersionRequested = MAKEWORD(2, 2);
WSADATA w_data;
int res = WSAStartup(wVersionRequested, &w_data);
if (res != 0) {
cout << "WSA Error with code " << WSAGetLastError() << endl;
return -1;
}
if (LOBYTE(w_data.wVersion) != 2 || HIBYTE(w_data.wVersion) != 2) {
cout << "Can not find suitable WSA version" << endl;
WSACleanup();
return -1;
}
return 0;
}
int main(int argc,char *argv[]) {
//初始化动态链接库
int res = startUp();
if (res == 0) {
cout << "WSA Start UP Success!" << endl;
}
else {
cout << "WSA start up error with code: " << WSAGetLastError() << endl;
return -1;
}
SOCKET s_sock;
SOCKADDR_IN se_addr;
memset(&se_addr, 0, sizeof(se_addr));
SOCKADDR_IN ec_addr;
//创建套接字
s_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (s_sock == INVALID_SOCKET) {
cout << "creat socket error with code: " << WSAGetLastError() << endl;
WSACleanup();
return -1;
}
cout << "creat socket success!" << endl;
//服务器端地址结构体
//要在程序里指定IP的话使用下面这两句
//char ip[] = "";
//se_addr.sin_addr.s_addr = inet_addr(ip);
se_addr.sin_family = AF_INET;
se_addr.sin_port = htons(SER_PORT);
se_addr.sin_addr.s_addr = inet_addr(argv[1]);
//对等端地址结构体
SOCKADDR_IN fr_addr;
memset(&fr_addr, 0, sizeof(fr_addr));
int llen = sizeof(se_addr);
int llen_2 = sizeof(fr_addr);
//接收缓冲
char rec[BUFF_LEN];
char send[BUFF_LEN];
int flag = 0;
int nNetTimeout = 10000;//10秒
//接收时限
setsockopt(s_sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&nNetTimeout, sizeof(int));
for (