【问题标题】:read() or write() functions are not workingread() 或 write() 函数不起作用
【发布时间】:2015-12-02 17:08:05
【问题描述】:

我正在尝试从套接字 fds 发送数据/读取数据

write() 和 read() 函数。

问题是其中一个不能正常工作,我解释一下:

write() 发送数据到 "sockfd" -> "sockfd" 使用 read() 函数将数据插入到 "answer" 变量

问题是当我尝试获取答案的内容时 (使用通常的 printf("%s\n",answer) ),它是空的。

我不知道问题是来自 read() 还是 write(),如果它们都失败了,它们会返回 -1,所以我添加了一个简单的检查来查看其中一个是否返回

代码下方:

这个是发件人,问题来自最后一次 write() 调用 [这个:if (write(client_sockfd,denied,sizeof(denied))

                                if(login_required(client_ipaddr) == 1)
                                {
                                  char getpasswd[256];
                                  char auth[256]="auth-required";
                                  char granted[9]="granted";
                                  char denied[7]="denied";
                                  //checks that password file exists!
                                  //check_passwd_file("passfile",client_sockfd);
                                  log_string("[CLIENT-AUTH]Authentication required! ...");
                                  write(client_sockfd,auth,sizeof(auth));
                                  read(client_sockfd,getpasswd,sizeof(getpasswd));
                                  //log_string(getpasswd);
                                  //check here
                                  if(strcmp(getpasswd,"jasmtest") == 0)
                                  {
                                    log_string("[PWD][OK]Password accepted!\n");
                                    log_string("[PWD][OK]Authorized!\n");
                                  }     
                                  else if(strcmp(getpasswd,"jasmtest") != 0)
                                  {
                                     log_error("[PWD][DEN]Wrong password!\n");
                                     log_error("[PWD][DEN]Closing connection...\n");
                                     if (write(client_sockfd,denied,sizeof(denied)) < 0)
                                       log_error("[core/ipc.c][start_server()][getpasswd][write()] ERROR while sending denied\n");
                                  }
                                }
                                else
                                {
                                  write(client_sockfd,not_required,sizeof(not_required));
                                  log_string("[CLIENT-AUTH]Authentication NOT required!");
                                }

这里是“客户” 我解释: 直到写(sockfd,get_my_pass,sizeof(get_my_pass)); 一切正常,当我打电话时: read(sockfd,answer,sizeof(answer)) 如上所述,它不再工作了。

read(sockfd,get_msg_from_server,255);

        if(strcmp(get_msg_from_server, "auth-required") == 0)
        {
          printf("+-----------------------------------------------------------------------+\n");
          printf("* Authentication is required before accessing JASM Command Line Interface\n");
          printf("* Password: \n");

          write(sockfd,get_my_pass,sizeof(get_my_pass));
          if(read(sockfd,answer,sizeof(answer)) < 0)
           printf("* Error on read\n");

          if(strcmp(answer,"denied") == 0)
          {
              printf("* Non-authorized access!!\n");
              printf("* Exiting...\n");
              close(sockfd);
              exit(3);
          }

        }
        else if(strcmp(get_msg_from_server, "auth-not-required") == 0)
          printf("* Authentication is not required for this session\n");

谢谢大家 :)

【问题讨论】:

  • 您的任何读取和/或写入是否成功?我注意到在代码的服务器部分中,第一次使用 read 和 write 无法检查返回值。根据您的套接字连接是如何实现的,您可能还会遇到一些同步阻塞问题。
  • 是的,以前的写/读都适用于两个源代码:/
  • 但是你怎么知道你是否没有检查返回值呢?此外,当您检查的写入返回错误时,errno 的值是多少?
  • 仅仅因为读取或写入系统调用返回并不意味着它成功。您需要每次检查返回值以确保它成功并确定读取或写入了多少字节。这是很好的编程习惯。当这些事情失败时,您还应该捕获errno 的值作为失败原因的指示。 perror 函数是获取此信息的一种相对简单的方法。
  • 仔细阅读文档,尤其是函数不返回 -1 时返回的内容。

标签: c linux sockets


【解决方案1】:

在大多数情况下,您不会检查 read()write() 调用的返回值。如果您传输超过一个字节,这始终是一个错误,因为即使没有发生 I/O 错误,这些函数也无法保证传输指定数量的字节。该数字给出了将被转移的最大值;您需要准备好通过多次调用传输所需的字节。

此外,在大多数情况下,您需要某种协议,每个阅读器都可以通过该协议预测要读取的字节数。如果您要发送固定长度的消息,那么作者和读者必须就消息长度达成一致;如果您要发送可变长度的消息,那么您需要每个消息的显式消息长度(本身是一个固定长度的组件)或读者可以识别的消息终止符。

你的案例有点说明问题。这是服务器写的:

write(client_sockfd,auth,sizeof(auth));

似乎打算与客户端的此读取配对:

read(sockfd,get_msg_from_server,255);

但请注意,auth 被声明为 char auth[256],因此其大小为 256。假设服务器确实写入了所有 256 个字节(正如我所说,不能保证),客户端最多读取它们中的255,至少留下一个等待,未读。 next 读取(进入answer)将从那个未读字节开始。它将是一个0(给定为auth 提供的初始化程序),因此answer 将被解释为一个空字符串,尽管该初始'\0' 后面可能有任何字节。

确实,即使服务器成功传输的字节数少于 256,如果它传输的字节数足以让客户端识别出包含字符串 "auth-required" 的消息,那么客户端读取的下一个字节的值将始终为零.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-25
    • 2021-01-13
    • 1970-01-01
    • 1970-01-01
    • 2013-01-30
    相关资源
    最近更新 更多