社区首页 >问答首页 >C++ WINSOCK在“攻击”后停止接受连接

C++ WINSOCK在“攻击”后停止接受连接
EN

Stack Overflow用户
提问于 2015-05-23 12:15:42
回答 2查看 1.4K关注 0票数 2

我在C++中有一个游戏服务器,我正在使用一个网络库,它在Windows中使用winsock。我一直在压力测试我的服务器,看看它一次能接受多少连接。当我使用我的游戏客户端连接时,它工作得很好,但是在我做了下面描述的压力测试之后,我的游戏客户端就不能再连接了。

压力测试是,我使用一个简单的程序for循环连接到我的服务器大约1000次,它只是启动与我的游戏服务器的tcp连接,并立即关闭它。它们都连接在一起。然后,之后,我试着连接我的游戏。这个游戏根本不相连。

我检查了库(参见下面的)的tcpaccept()函数,没有输出。由于某种原因,accept()在我对1000个连接的“攻击”之后停止接受连接。什么能让我的服务器停止接受连接呢?

下面是我的循环总结,它侦听并接受连接并关闭它们:

代码语言:javascript
代码运行次数:0
复制
bool serverIsOn = true;
double listen = tcplisten(12345, 30000, 1);
setnagle(listen, true);

...

while(serverIsOn){
    double playerSocket = tcpaccept(listen, 1);
    if(playerSocket > -1){
        cout << "Got a new connection, socket ID: " << playerSocket << endl;

        //add their sockID to list here!
        addSockIDToList(playerSocket);

    }

    //Loop through list of socks and parse their messages here..
    //If their message size == 0, we close their socket via closesocket(sockID);
    loopThroughSocketIdsAndCloseOnLeave();
}

cout << "Finished!" << endl;

以下是tcplisten、tcpaccept、CSocket::CSocket(套接字)、CSocket::tcplisten(.)的定义和CSocket::tcpaccept(.):

代码语言:javascript
代码运行次数:0
复制
double tcplisten(int port, int max, int mode)
{
    CSocket* sock = new CSocket();
    if(sock->tcplisten(port, max, mode))
        return AddSocket(sock);
    delete sock;
    return -1;
}

double tcpaccept(int sockid, int mode)
{
    CSocket*sock = (CSocket*)sockets.item(sockid);
    if(sock == NULL)return -1;
    CSocket*sock2 = sock->tcpaccept(mode);
    if(sock2 != NULL)return AddSocket(sock2);
    return -1;
}

...

CSocket::CSocket(SOCKET sock)
{
    sockid = sock;
    udp = false;
    format = 0;
}

bool CSocket::tcplisten(int port, int max, int mode)
{
    if((sockid = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) return false;
    SOCKADDR_IN addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = INADDR_ANY;
    addr.sin_port = htons(port);
    if(mode)setsync(1);
    if(bind(sockid, (LPSOCKADDR)&addr, sizeof(SOCKADDR_IN)) == SOCKET_ERROR)
    {
        closesocket(sockid);
        return false;
    }
    if(listen(sockid, max) == SOCKET_ERROR)
    {
        closesocket(sockid);
        sockid = INVALID_SOCKET;
        return false;
    }
    return true;
}


CSocket* CSocket::tcpaccept(int mode)
{
    if(sockid == INVALID_SOCKET) return NULL;
    SOCKET sock2;
    if((sock2 = accept(sockid, (SOCKADDR *)&SenderAddr, &SenderAddrSize)) != INVALID_SOCKET)
    {
        //This does NOT get output after that 1000-'attack' test.
        std::cout << "Accepted new connection!" << std::endl;
        CSocket*sockit = new CSocket(sock2);
        if(mode >=1)sockit->setsync(1);
        return sockit;
    }

    return NULL;
}

在我的1000连接压力测试之后,我能做些什么来找出为什么accept()不再接受连接?这与我在他们结束后关闭联系的方式有关吗?当我这么做的时候,我所做的就是打电话:closesocket(sockID).

请询问所需的任何其他代码!

编辑:-我刚刚注意到我的“压力测试”java程序668倍连接后出现异常。这是一个例外:

线程"main“中的异常( java.net.ConnectException: Connection拒绝:Connection at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79),at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79),at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339),at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200),at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182),at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172),at java)。net.SocksSocketImpl.connect(SocksSocketImpl.java:392) at java.net.Socket.connect(Socket.java:579) at java.net.Socket.connect(Socket.java:528) at java.net.Socket.(Socket.java:425) at java.net.Socket.(Socket.java:208) at Socket.java:528

EN

回答 2

Stack Overflow用户

发布于 2015-05-23 12:52:55

因为您的服务器端正在关闭套接字,所以它们很可能在time_wait中停留几分钟。Windows具有控制最大套接字和各种状态的各种参数。我猜您的程序在几分钟后再次开始工作,并且可能会在事件查看器中出现一些警告。

另一种选择可能是忽略这些套接字几分钟,并希望它们消失。当您完全没有响应时,客户端会调用closesocket,这意味着您不会招致time_wait。这通常是可行的,但并非总是如此。如果没有,则在后台缓慢地调用closesocket()。

如果您真的想要,您可以重置连接,详细信息请参阅LINGER (zero) - when it's required,但是重新设置连接是不正常的,所以一定要广泛阅读关于So_linger和teardown是如何工作的。

票数 1
EN

Stack Overflow用户

发布于 2015-05-23 14:40:34

事实证明,这个库有自己的关闭套接字的方法:

代码语言:javascript
代码运行次数:0
复制
int closesock(int sockid)
{
    CSocket*sock = (CSocket*)sockets.item(sockid);
    if(sock == NULL)return -1;
    delete sock;
    sockets.set((int)sockid, NULL);
    return 1;
}

因此,它通过套接字列表中的sockID获取当前套接字。然后,如果sockID与有效的套接字相关,则删除sock对象并在套接字列表中将其设置为NULL。

问题是,我只是调用closesocket(sockID)而不是closesock(sockID),后者执行了关闭套接字所需的必要操作。

谢谢大家的帮助。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30417144

复制
相关文章
go 中 struct 是否可以比较?
今天来水一篇,最近比较忙,一直没有时间写 go 相关的,今天从一个小问题入手,来说说 struct 的比较问题。
LinkinStar
2022/09/01
8400
Redis是否可以存图片、视频?
前几天看到某大型家电工厂的工业互联网系统架构图,发现用MongoDB存储图片及视频。那Redis同样也是Json类型的远程数据字典服务器,也可以用于存储图片、视频。实际Redis可以用512MB的空间存储用于存储字符串型的数据。
希望的田野
2019/09/24
9.7K0
Redis是否可以存图片、视频?
Docker容器是否可以改变世界?
2016年了,很多大牛开始预测技术趋势,其中一个普遍的观点我也很认同: Docker会更加流行,会改变程序世界 2015年的上半年我接触了Docker,熟悉之后,真有一点震惊的感觉,太方便了,可以解决很多问题 Container 通常翻译为容器,但还有另一个意思,就是“集装箱” 集装箱是21世纪最伟大的发明之一,它改变了世界货物运输体系,造就了一个高度自动化、标准化、低成本的物流体系,促进了经济的全球化发展 程序界也出现了同样的一个箱子,就是 Docker容器 Docker的核心特点 Docker是一个开源
dys
2018/04/03
6490
Docker容器是否可以改变世界?
在C中,如何知道动态分配是否成功
C语言使用 malloc函数动态在堆上分配内存。malloc根据字节数的参数。如果无法分配内存,该函数将返回指向已分配内存的指针或 NULL 指针。
mariolu
2021/11/06
2.7K0
容器是否可以取代虚机?
在 Docker 诞生之初,它常常被放在虚拟机技术的对立面,甚至还有过 Docker 将替代虚拟机的夸大宣传,在许多集群以及虚拟化方案设计的讨论中,也总会将两者拿来比较一番利弊。
孙杰
2019/10/29
2.3K0
三十、是否可以使用 count(*)
一、是否可以使用 count(*) 在 SQL 中,COUNT() 函数返回匹配指定条件的函数。 序号COUNT用法作用描述1COUNT(*)返回总记录数,包含 NULL 值2COUNT(1)与COUNT(*)的作用一样3COUNT(column_name)返回指定列的数目,NULL值不统计4COUNT(DISTINCT column_name)返回指定列不同值的数目,NULL值不统计 Tip: COUNT(*) 与 COUNT(column_name) 的作用不一样,如果列值包含 NULL ,统计结果就
喵叔
2022/05/06
4720
判断数组中任意数据累加是否可以得到aim
给你一个数组arr,和一个整数aim。 如果可以任意选择arr中的数字,能不能累加得到aim,返回true或者false
名字是乱打的
2022/05/13
3700
Spark是否可以完全取代Hadoop
谈到大数据,相信大家对Hadoop和Apache Spark这两个名字并不陌生。然而,最近业界有一些人正在大张旗鼓的宣扬Hadoop将死,Spark将立。他们究竟是危言耸听、哗众取宠,还是眼光独到堪破
企鹅号小编
2018/02/02
1.9K0
Spark是否可以完全取代Hadoop
Java中是否直接可以使用enum进行传输
我们在进行传输的时候 会有一些状态值,如Status为1代表删除,为0代表失败或者怎么样的。只传输一个)0或者1过去给第三方(此处不包括给前端),如果没有契约第三方会不认识你这个是什么意思,那我们在平时写业务逻辑的时候使用枚举很轻易就知道了什么状态什么值。所以我们在构建DTO对象的时候里面放一个枚举来表示。
袁新栋-jeff.yuan
2020/08/26
3.9K0
有了它,AI甚至可以让你知道对方是否真的爱你?
“你到底爱不爱我?”这或许是恋爱双方出现频率最高的问题,想要知道对方大脑在想什么,并不是什么天方夜谭,通过科学技术还真的有望实现。不过,让如此大胆的想法变为现实,我们需要借助什么技术呢?我想,目前最火的人工智能技术应该首先出列。
AI科技大本营
2019/05/07
4010
有了它,AI甚至可以让你知道对方是否真的爱你?
VBA判断单元格是否为字母
【问题】:我们在工作中,有时候要判断人家输入单元格是内容中的数据是首字母含有字母还是内容其中含有字母。
哆哆Excel
2022/10/25
1K0
VBA判断单元格是否为字母
检测表中行记录是否已存在
检查PG表中行记录是否已存在,可通过发起一个select看下是否有行记录返回,但是依赖于如何做到这点,返回的结果可能比较奇怪或者不太高效。
yzsDBA
2021/01/05
1K0
MediaCodec判断是否可以采用硬解码
具体的类型对应关系可以查看相关文档,这里在Android源码MediaCodec.createDecoderByType()里面有一些相关的对应支持类型。
曾大稳
2018/09/11
2.2K0
SQL里是否可以使用JOIN
很多公司都禁止程序员在 SQL 中使用 JOIN,至于原因则出奇的一致:用 JOIN 慢。不过我从没见过谁来论证为什么用 JOIN 慢,结果这个人云亦云的结论越传越广,让我觉得是时候来讨论一下这个看似正确的结论了。
LA0WAN9
2021/12/14
5640
SQL里是否可以使用JOIN
POI判断某个单元格是否是合并单元格
注:比如我们的数据是上面N个单元组成,且每个单元所占行数可能不同。第一列占据一列,中间数据每个占用一个单元格,最后一列与第一列占用相同的行数,这时我们需要获取起始单元格占用几行(起始行--结束行),获取到这些数据后我们就能读取中间单元格数据(这些数据可以作为上面单元的一个属性),下面给出具体代码:
johnhuster的分享
2022/03/28
3.2K0
POI判断某个单元格是否是合并单元格
是否可以删除 WinSxS 文件夹
一个常见问题是,“是否可以删除 WinSxS 文件夹来重新获得磁盘空间?” 简短的答案是“否”。但是,可以使用 Windows 中内置的工具来减小 WinSxS 文件夹的大小。
Windows技术交流
2020/04/13
5.2K0
因子投资:价值和动量是否已死?
从历史上来看,至少通过标普500指数衡量的“股市”一直有着史诗般的表现——特别是与其它几乎所有大类资产对比时更能印证这一点。无论你是按地理位置(例如美国,发达国家,新兴市场),风格(例如价值,动量)或类型(例如股票,债券,商品)来看其他大类资产,一件事是非常明显的:标普500指数是当之无愧的王。
量化投资与机器学习微信公众号
2019/05/09
1.1K0
因子投资:价值和动量是否已死?
Python: 判断某个Excel文件是否已打开
文章背景:在操作某个Excel文件时,有时想看看某个Excel文件是否已打开。下面提供两种自定义函数。
Exploring
2022/09/20
3.2K0
Django ajax 检测用户名是否已
添加一个 register.html 页面 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form> <p>用户名<input id="username" type="text" name="username" onblur="func1(this)" /> <span id="error"></span>
py3study
2020/01/15
1.1K0
Django ajax 检测用户名是否已
点击加载更多

相似问题

Bashrc不在Ubuntu 20.04.1上运行

10

Ubuntu12.04上意外删除的.bashrc

20

我的世界不会在Ubuntu上运行

10

文件.bashrc Ubuntu18.04的意外结束

20

安装后Ubuntu不会在我的chromebook上启动

10
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文