在Windows上实现相同功能的代码需要做一些修改,因为Windows使用不同的网络API(如Winsock)。以下是基于你提供的Linux代码转换后的Windows版本。
注意:这个示例仍然是一个基础版本,你可能需要根据具体情况进行优化和调整。请确保在Windows环境中包含winsock2.h
和其他必要的头文件。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <errno.h>
#include <time.h>
#define MAX_BUFFER 128
#define MAX_EPOLLSIZE (384*1024)
#define MAX_PORT 100
#define TIME_SUB_MS(tv1, tv2) ((tv1.tv_sec - tv2.tv_sec) * 1000 + (tv1.tv_usec - tv2.tv_usec) / 1000)
int isContinue = 0;
static int ntySetNonblock(SOCKET fd) {
u_long mode = 1; // non-blocking mode
return ioctlsocket(fd, FIONBIO, &mode);
}
static int ntySetReUseAddr(SOCKET fd) {
int reuse = 1;
return setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse));
}
int main(int argc, char **argv) {
if (argc <= 2) {
printf("Usage: %s ip port\n", argv[0]);
exit(0);
}
const char *ip = argv[1];
int port = atoi(argv[2]);
int connections = 0;
char buffer[MAX_BUFFER] = {0};
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
printf("WSAStartup failed.\n");
return -1;
}
struct sockaddr_in addr;
memset(&addr, 0, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(ip);
struct timeval tv_begin;
GetSystemTimeAsFileTime((FILETIME*)&tv_begin);
while (1) {
static int index = 0;
if (++index >= MAX_PORT) index = 0;
SOCKET sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sockfd == INVALID_SOCKET) {
perror("socket");
break;
}
addr.sin_port = htons(port + index);
if (connect(sockfd, (struct sockaddr*)&addr, sizeof(struct sockaddr_in)) == SOCKET_ERROR) {
perror("connect");
closesocket(sockfd);
continue;
}
ntySetNonblock(sockfd);
ntySetReUseAddr(sockfd);
sprintf(buffer, "Hello Server: client --> %d\n", connections);
send(sockfd, buffer, strlen(buffer), 0);
connections++;
if (connections % 1000 == 999 || connections >= MAX_EPOLLSIZE) {
GetSystemTimeAsFileTime((FILETIME*)&tv_cur);
int time_used = TIME_SUB_MS(tv_cur.dwLowDateTime/10000ULL,
tv_begin.dwLowDateTime/10000ULL);
printf("connections: %d\n", connections);
fd_set read_fds;
FD_ZERO(&read_fds);
FD_SET(sockfd,&read_fds);
struct timeval timeout;
timeout.tv_sec=1;
timeout.tv_usec=0;
if(select(sockfd+1,&read_fds,NULL,NULL,&timeout)>0){
char rBuffer[MAX_BUFFER] = {0};
recv(sockfd,rBuffer,sizeof(rBuffer)-1 ,NULL);
printf("RecvBuffer:%s\n", rBuffer);
if (!strcmp(rBuffer,"quit")) {
isContinue=0;
}
close(sockfd); // Clean up
}else{
perror("recv failed");
}
}
Sleep(1); // sleep for a short duration
}
WSACleanup();
return 0;
err:
printf("error : %s\n", strerror(errno));
return -1;
}
注意事项:
- 在编译时,请确保链接到 Winsock 库 (
Ws2_32.lib
)。 - 使用
WSAStartup
和WSACleanup
初始化和清理 Winsock。 - Windows 中没有
epoll
,因此我们使用了select
来处理 IO 多路复用。 - 使用
Sleep()
而不是usleep()
来替代 Linux 的毫秒级睡眠函数。
确保在Windows系统中测试此代码并根据你的需求进一步优化!
内容由零声教学AI助手提供,问题来源于学员提问