鱼C论坛

 找回密码
 立即注册
查看: 107|回复: 1

[已解决]请大家看下程序错在哪里

[复制链接]
发表于 2025-4-28 20:52:37 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

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;
}
最佳答案
2025-4-28 20:53:53
问题分析及解决方案

你的代码问题出在 listen() 函数参数理解有误!Windows 的 backlog 参数实际最大会被系统修正为 200(即使你设置2)。这是微软的设计特性,不是代码错误。

关键问题说明
  • listen(sListen, 2) 中的2表示 等待队列长度,但Windows会自动取 min(backlog, 200)
  • 实际测试时超过2仍能连接,是因为系统自动扩展了队列容量
  • 真正的并发控制需要自行实现(如计数器+连接拒绝逻辑)


改进建议代码
在 accept 后添加连接计数控制:


  1. int max_connections = 2;
  2. int current_connections = 0;

  3. while(true)
  4. {
  5.     SOCKET sClient = accept(sListen, (SOCKADDR*)&addrClient, &addrClientlen);
  6.     if (sClient == INVALID_SOCKET) {
  7.         cout << "accept error!" << endl;
  8.         continue;
  9.     }

  10.     // 新增连接数控制
  11.     if(current_connections >= max_connections) {
  12.         cout << "连接数已达上限,拒绝新连接" << endl;
  13.         closesocket(sClient);
  14.         continue;
  15.     }
  16.    
  17.     current_connections++;
  18.     cout << "当前连接数:" << current_connections << endl;
  19.    
  20.     // 这里应该创建线程处理客户端请求
  21.     // 处理完成后需要 current_connections--;
  22.    
  23.     closesocket(sClient); // 注意:实际项目不要立即关闭!
  24. }
复制代码


注意事项
  • 实际项目中要用多线程处理连接
  • 每次关闭客户端socket前应完成数据通信
  • 建议学习 selectIOCP 模型处理高并发


完整教学视频参考:
fishc.com.cn/forum.php?mod=viewthread&tid=100000&extra=page%3D1 (示例链接,请替换为实际课程链接)

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2025-4-28 20:53:53 | 显示全部楼层    本楼为最佳答案   
问题分析及解决方案

你的代码问题出在 listen() 函数参数理解有误!Windows 的 backlog 参数实际最大会被系统修正为 200(即使你设置2)。这是微软的设计特性,不是代码错误。

关键问题说明
  • listen(sListen, 2) 中的2表示 等待队列长度,但Windows会自动取 min(backlog, 200)
  • 实际测试时超过2仍能连接,是因为系统自动扩展了队列容量
  • 真正的并发控制需要自行实现(如计数器+连接拒绝逻辑)


改进建议代码
在 accept 后添加连接计数控制:


  1. int max_connections = 2;
  2. int current_connections = 0;

  3. while(true)
  4. {
  5.     SOCKET sClient = accept(sListen, (SOCKADDR*)&addrClient, &addrClientlen);
  6.     if (sClient == INVALID_SOCKET) {
  7.         cout << "accept error!" << endl;
  8.         continue;
  9.     }

  10.     // 新增连接数控制
  11.     if(current_connections >= max_connections) {
  12.         cout << "连接数已达上限,拒绝新连接" << endl;
  13.         closesocket(sClient);
  14.         continue;
  15.     }
  16.    
  17.     current_connections++;
  18.     cout << "当前连接数:" << current_connections << endl;
  19.    
  20.     // 这里应该创建线程处理客户端请求
  21.     // 处理完成后需要 current_connections--;
  22.    
  23.     closesocket(sClient); // 注意:实际项目不要立即关闭!
  24. }
复制代码


注意事项
  • 实际项目中要用多线程处理连接
  • 每次关闭客户端socket前应完成数据通信
  • 建议学习 selectIOCP 模型处理高并发


完整教学视频参考:
fishc.com.cn/forum.php?mod=viewthread&tid=100000&extra=page%3D1 (示例链接,请替换为实际课程链接)

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-5-12 15:00

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表