我需要帮助找出 tcp 套接字 (clsocket)

Posted

技术标签:

【中文标题】我需要帮助找出 tcp 套接字 (clsocket)【英文标题】:I need help figuring out tcp sockets (clsocket) 【发布时间】:2021-12-19 16:55:45 【问题描述】:

我无法确定套接字,我只是向服务器询问某个位置的数据 (glm::i64vec4) 并期待响应 但是当我得到响应和数据时,位置就会偏离位置反映了这一点(也就是我的体素游戏看起来很酷但没用) 可能只是我不了解套接字,或者这个库可能有些奇怪 我的一个想法是这可能与服务器和客户端上不匹配的阻塞和非阻塞有关 但是当我将服务器切换到阻塞状态时(并将每个客户端放在一个单独的线程中,并与接受进程分开),它什么也没做 如果我在做一些非常愚蠢的事情,请告诉我我对套接字几乎一无所知

这是一些可能看起来很糟糕的代码

服务器代码

std::deque <CActiveSocket*> clients;
CPassiveSocket socket;
socket.Initialize();
socket.SetNonblocking();//I'm doing this so i don't need multiple threads for clients
socket.Listen("0.0.0.0",port);
while (1)
    
        CActiveSocket* c;
        if ((c = socket.Accept()) != NULL)
            clients.emplace_back(c);
        
    

    for (CActiveSocket*& c : clients)
        c->Receive(sizeof(glm::i64vec4));
        if (c->GetBytesReceived() == sizeof(glm::i64vec4))
            chkpkt chk;
            chk.pos = *(glm::i64vec4*)c->GetData();

            LOOP3D(chksize+2)
                chk.data(i,j,k).val = chk.pos.y*chksize+j;
                chk.data(i,j,k).id=0;
            
            while (c->Send((uint8*)&chk,sizeof(chkpkt)) != sizeof(chkpkt))
        

    

客户代码

//v is a glm::i64vec4
//fsock is set to Blocking

if(fsock.Send((uint8*)&v,sizeof(glm::i64vec4)))
    if (fsock.Receive(sizeof(chkpkt)))
        tthread::lock_guard<tthread::fast_mutex> lock(wld->filemut);
        wld->ichks[v]=(*(chkpkt*)fsock.GetData()).data;//i tried using the position i get back from the server to set this (instead of v) but that made it to where nothing loaded
        //i checked it and the chunks position never lines up with what i sent
    

【问题讨论】:

【参考方案1】:

如果没有完整的应用程序代码,就任何特定的代码更正行提供任何建议是不现实的。

但您似乎正在使用this 库。如果没有也没关系,因为大多数时候在进行网络编程时,socket 的怪异行为使一些问题具有一定的普遍性。因此,对于您项目中的套接字应用程序部分有一些建议:

    拥有 BLOCKING 套接字就足够了。 大多数时候套接字的read 有一些奇怪的行为,即它可能一次无法接收请求大小的字节。因此,您需要反复调用read,直到彻底读取接收缓冲区。如需完整且强大的解决方案,您可以参考 Stevens 的 readn 例程([Ref.1],第 122 页)。

如果您使用的正是上面提到的库,您可以看到您的fsock.Receive 最终调用了recv。而recv 只是read 的变体[Ref.2],因此它们的解决方案完全相同。这种模式可能会有所帮助:

while(fsock.Receive(sizeof(chkpkt))>0)

  // ...

参考 1:https://mathcs.clarku.edu/~jbreecher/cs280/UNIX%20Network%20Programming(Volume1,3rd).pdf 参考2:https://man7.org/linux/man-pages/man2/recv.2.html#DESCRIPTION

【讨论】:

以上是关于我需要帮助找出 tcp 套接字 (clsocket)的主要内容,如果未能解决你的问题,请参考以下文章

C++ UNIX 帮助 - 简单的 TCP 服务器套接字连接

帮助理解 linux/tcp.h

使用 tcp 套接字在 windows phone 7 上解析 xml 内容

Javascript 套接字连接

在 java /android 中提高 TCP 套接字的传输速度

检测 TCP 何时拥塞 python 扭曲套接字服务器