【问题标题】:I need help figuring out tcp sockets (clsocket)我需要帮助找出 tcp 套接字 (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
    }

【问题讨论】:

    标签: c++ sockets tcp voxel


    【解决方案1】:

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

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

    1. 拥有 BLOCKING 套接字就足够了。
    2. 大多数时候套接字的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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-11
      • 2013-06-14
      • 2022-01-17
      • 2016-05-25
      • 2011-03-11
      • 2018-07-24
      • 2022-01-14
      • 2015-08-17
      相关资源
      最近更新 更多