|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
刚学习socket编程,仿照教学视频,分别编写了windows下的服务端和客户端程序。设定连接数为2,
但是实际运行时,当连接数超过2时,还是正常运行。从网上找些程序对比,也没找出来错在哪里,
现把服务端程序发布如下,请大神们帮忙看下什么毛病?
;server.cpp
#include <iostream>
#include<WinSock2.h>
#include <WS2tcpip.h> // 添加这个头文件
#pragma comment(lib,"WS2_32")
using namespace std;
#include <stdio.h>
int main()
{
cout << "this is Server windows" << endl;
////初始化网络库
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
cout << "Failed to initialize Windsock" << endl;
return 1;
}
//创建监听套接字
SOCKET listenSocket = socket(AF_INET, SOCK_STREAM, 0);
if (listenSocket == INVALID_SOCKET)
{
cout << "Failed to create socket" << endl;
WSACleanup();
return 1;
}
//设置服务器地址和端口
sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = INADDR_ANY;
serverAddr.sin_port = htons(6000);
//绑定监听端口
if (bind(listenSocket, (sockaddr*)&serverAddr, sizeof(serverAddr)) < 0)
{
cout << "Failed to bind socket." << endl;
closesocket(listenSocket);
WSACleanup();
return 1;
}
//建立监听状态
if (listen(listenSocket, 2) < 0)
{
cout << "Failed to listen onf socket." << endl;
closesocket(listenSocket);
WSACleanup();
return 1;
}
//接收客户端连接,并新建和客户端通信的套接字clientSocket
//循环监听,并处理信息
int len = sizeof(sockaddr);
while (true)
{
SOCKET clientSocket = accept(listenSocket, (sockaddr*)&serverAddr, &len);
if (clientSocket == INVALID_SOCKET)
{
cout << "Failed to accept client connection" << endl;
continue;
}
char revBuffer[1024] = "";
if (recv(clientSocket, revBuffer, sizeof(revBuffer), 0) == SOCKET_ERROR)
{
cout << "Failed to receive data" << endl;
closesocket(clientSocket);
continue;
}
cout << "recive client:" << revBuffer << endl;
string message = "server:hello client";
if (send(clientSocket, message.c_str(), message.size(), 0) == SOCKET_ERROR)
{
cout << "Failed to send data" << endl;
}
closesocket(clientSocket);
}
closesocket(listenSocket);
WSACleanup();
return 0;
}
问题分析及解决方案
你的代码问题出在 listen() 函数参数理解有误!Windows 的 backlog 参数实际最大会被系统修正为 200(即使你设置2)。这是微软的设计特性,不是代码错误。
关键问题说明
- listen(sListen, 2) 中的2表示 等待队列长度,但Windows会自动取 min(backlog, 200)
- 实际测试时超过2仍能连接,是因为系统自动扩展了队列容量
- 真正的并发控制需要自行实现(如计数器+连接拒绝逻辑)
改进建议代码
在 accept 后添加连接计数控制:
- int max_connections = 2;
- int current_connections = 0;
- while(true)
- {
- SOCKET sClient = accept(sListen, (SOCKADDR*)&addrClient, &addrClientlen);
- if (sClient == INVALID_SOCKET) {
- cout << "accept error!" << endl;
- continue;
- }
- // 新增连接数控制
- if(current_connections >= max_connections) {
- cout << "连接数已达上限,拒绝新连接" << endl;
- closesocket(sClient);
- continue;
- }
-
- current_connections++;
- cout << "当前连接数:" << current_connections << endl;
-
- // 这里应该创建线程处理客户端请求
- // 处理完成后需要 current_connections--;
-
- closesocket(sClient); // 注意:实际项目不要立即关闭!
- }
复制代码
注意事项
- 实际项目中要用多线程处理连接
- 每次关闭客户端socket前应完成数据通信
- 建议学习 select 或 IOCP 模型处理高并发
完整教学视频参考:
fishc.com.cn/forum.php?mod=viewthread&tid=100000&extra=page%3D1 (示例链接,请替换为实际课程链接)
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
|
|