【问题标题】:problems with double send/recv双重发送/接收问题
【发布时间】:2012-07-14 01:15:19
【问题描述】:

我的发送/接收有问题:如果客户端发送两个字符串,服务器仅在一个接收中接收两个字符串,第二个接收参与来自客户端的第三次发送(我不想发送)。我想发送 2 个字符串并接收 2 个字符串。我该怎么办?

我的代码: 客户

char login[] = "admin";
char password[] = "admin";

send(sd, login, strlen(login), 0);
send(sd, password, strlen(password), 0);

服务器:

bzero(login,MAX);
bzero(password,MAX);

recv(sd_client, login, sizeof(login), 0);
recv(sd_client, password, sizeof(password), 0);

【问题讨论】:

    标签: c sockets send recv


    【解决方案1】:

    我假设您在服务器端使用两个字符数组作为变量“登录”和“密码”。

    在这种情况下,为了创建它们,您必须在其声明中给它们一个固定大小,这个数组的大小是多少?MAX宏的大小是多少?

    在您的客户端中,您使用的是 5 个长度的数组,如果 MAX 宏的长度超过 10 个字节,那么第一个 recv() 将读取两个发送。

    【讨论】:

    • 客户端和服务器的 MAX 定义为 8192,但不存在 TCP 接收/发送的“STOP”字符(如字符串中的 \0)?
    • @myself 恐怕不行,你要知道你要发送和接收的数据的大小,如果服务器的数组是8192字节长,那么你必须发送8192字节,第一个五个必须是“管理员”,第六个是“\0”,其余的都可以是零或垃圾。
    【解决方案2】:

    TCP 无法发送/接收字符串。 TCP 不能发送/接收超过一个字节的消息。 TCP 不能发送/接收长度超过一个字节的结构体。

    TCP 传输是字节流。

    如果你想传输比一个字节更复杂的东西,你需要一个额外的协议,因此是 HTTP、SMTP 等协议。

    例如,如果您特别想发送以空值结尾的字符串,则需要缓冲并连接接收到的数据,直到检测到空值 - 那么您就有了“C”风格的字符串,并且可以继续组装下一个字符串。

    Rgds, 马丁

    【讨论】:

    • 在接收和发送之间使用 sleep(1) 是个好主意吗?它有效!
    • 不,它没有。您正在做的是在每次交易所中抽奖。这是你的幸运日/环境:) 如果你在不同的链接等上做更多的测试,你会输得很惨:) 不要试图提供这样的解决方案——它不会起作用。您必须以这样一种方式正确和正确地组装您的字符串,以便无论在每个 recv() 调用中是否占用 10000 个字节中的 1 个字节,它都能正常工作。其他任何事情都会破坏:(
    • @myself,我认为不是,因为 TCP 协议实现了一个可靠的连接,自动等待数据所需的时间。
    • @JLledo - 是的,如果知道数据的大小,您可以等待它 - 这是协议定义:) 通常,用户名/密码的长度不同,在登录之前无法知道.
    • 套接字编程最常见的错误之一是“你发送() 的大小就是你接收() 的长度”。消息的合并和分段使得 recv() 的返回值成为一个非常不可预测的值。但是如果你这样对待它,你可以拥有一个非常健壮的协议实现。
    猜你喜欢
    • 1970-01-01
    • 2018-08-30
    • 2012-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-25
    • 1970-01-01
    相关资源
    最近更新 更多