2

我想在 c/c++ 中使用 win socket 制作一个聊天程序。(我完全是新手。)第一个问题是关于如何检查客户端是否从服务器接收到数据包。例如,服务器向客户端发送“aaaa”。如果客户端没有收到数据包“aaaa”,服务器应该再次重新发送数据包。(我认为)。但是,我不知道如何检查它。这是我的想法。第一种情况。


服务器---“aaaa”--->客户端。
服务器将检查等待来自客户端的确认消息的时间。
客户端---“我收到了”--->服务器。
服务器不会重新发送数据包。


另一种情况。
服务器---“aaaa”--->客户端。
服务器正在等待客户端消息,直到超时
服务器---“aaaa”--->再次客户端。

但这些可能是不合适的。看第二种情况。服务器正在等待来自客户端的消息一段时间。如果超时,服务器将再次重新发送数据包。在这种情况下,客户端可能会收到两次数据包。

第二个问题是如何发送无限大小的数据包。一本书说数据包应该有类型、大小和消息。跟着它,我只能发送一定大小的味精。但我想发送 1Mbytes 或更多的味精。(无限制)

怎么做?

任何人都有任何好的链接或尽可能简单地向我解释正确的逻辑。

谢谢。

4

2 回答 2

1

使用 TCP。在应用程序级别考虑“消息”,而不是数据包。

TCP 已经处理网络级数据包数据、错误检查和重新发送丢失的数据包。它以字节“流”的形式将其呈现给应用程序,但不一定保证交付(因为任何一端都可以强制断开连接)。

因此,在应用程序级别,您需要处理消息接收和缓冲——重新连接的客户端能够请求以前的消息,这些消息他们还没有(还)正确接收。

下面是一些数据结构:

class or struct Message {
    int type;              // const MESSAGE.
    int messageNumber;     // sequentially incrementing.
    int size;              // 4 bytes, probably signed;  allows up to 2GB data.
    byte[] data;
}

class or struct Receipt {
    int type;              // const RECEIPT.
    int messageNumber;     // last #, successfully received.
}

您可能还需要一个 Connect/Hello 和一个 Disconnect/Goodbye 握手。

class Connect {
    int type;              // const CONNECT.
    int lastReceivedMsgNo; // last #, successfully received.
    // plus, who they are?   
    short nameLen;
    char[] name;
}

等等

如果您可以非常简单并且不需要缓冲/重新发送消息以重新连接客户端,那就更简单了。

您还可以采用“统一消息结构”,其中 TYPE 和 SIZE(4 字节整数)作为每个消息或握手的前两个字段。这可能有助于标准化您处理这些的例程,但会牺牲一些冗余(例如,在“名称”字段大小中)。

于 2013-08-06T02:40:05.597 回答
1

对于第一部分,看看 TCP。它提供有序且可靠的数据包传输。另外,您可以通过使用 UDP 自己实现它来进行大量自定义。从广义上讲,它的作用是,

服务器: 1. 为每个数据包编号并发送 2. 等待特定数据包编号的确认。然后重新传输丢失的数据包。

客户端: 1. 接收一个数据包并维护一个缓冲区(滑动窗口) 2. 它继续收集缓冲区中的数据包,直到缓冲区溢出或错误顺序的数据包到达。一旦它发生,具有正确序列的数据包就会被“传递”,并且最后一个正确数据包的序列号会在确认中发送。

对于第二部分:我会使用 HTTP。经过一些修改。就像您应该有一些非常独特的指标来告诉客户现在传输已完成等

于 2013-08-06T02:31:52.130 回答