【问题标题】:why it can be "bad file number" when i write to socket为什么当我写入套接字时它可能是“错误的文件号”
【发布时间】:2012-03-27 02:20:29
【问题描述】:

我在从客户端向服务器套接字发送消息时遇到问题。 write 函数返回错误 - 错误的文件号。这意味着我无权写入此套接字。 但是从另一个客户端我可以写入这个套接字,并成功完成。 最有趣的是,当另一个客户端连接到服务器时,我的(问题)客户端也可以发送消息。

我的客户的代码:

SOCKET OnceCommand;
struct sockaddr_in SAddress4;

struct autoC
{
  char buf[4];
  short fromx;
  short fromy;
  short tox;
  short toy;
  char step;
  char cycle;
};
union autocomm{
  char byte[14];
  struct autoC command;
} Command1, Command2;

memset(&SAddress4,0,sizeof(SAddress4));
SAddress4.sin_family = AF_INET;
SAddress4.sin_port = htons(444);
SAddress4.sin_addr.s_addr = inet_addr(RobotsIP[Robot1]);
memset(&(SAddress4.sin_zero),0,8);

if((OnceCommand = socket(AF_INET,SOCK_STREAM,0))!=SOCKET_ERROR)
{
  Err(OnceCommand);
  if(conn = connect(OnceCommand,(struct sockaddr *)&SAddress4,sizeof(struct sockaddr))!=SOCKET_ERROR)
  {
    rc = write(OnceCommand,(char*)Command1.byte,sizeof(Command1.byte));
    if(rc < 0)
    {
      perror("Client-write() error");
      rc = getsockopt(OnceCommand, SOL_SOCKET, SO_ERROR, &temp, &length);
      if(rc == 0)
      {
        Err(OnceCommand);
        perror("SO_ERROR was");
      }
      closesocket(OnceCommand);
    }
    else
    {
      adv_printf("Client-write() is OK\n");
      adv_printf("String successfully sent lol!\n");
    }
    shutdown(OnceCommand,2);
    closesocket(OnceCommand);
  }
}

在 SO_ERROR 中是“错误的文件号”

我在基于 ROM-DOS 的 ADAM-5510 微控制器中使用套接字库。

我试图通过使用非阻塞套接字来解决这个问题,但 select 只返回读取就绪标志。

【问题讨论】:

  • 这可能会解决与您报告的问题不同的问题,但write(OnceCommand,(char*)Command1.byte,sizeof(Command1.byte)); 是否应该将&amp;Command1.byte 作为第二个参数,它应该是指向您要写入的数据的指针?
  • Command1 - 是一个具有名为“byte”的结构和大量字符的联合。我认为在这种情况下没有区别。但我检查了一下,它仍然返回我的“错误文件号”错误:(
  • 你真的应该更恰当地标记这个问题。它看起来不像是有效的套接字代码,而是一些像 winsock 这样的非标准变体......这可能会对错误的报告方式以及perror 是否打印有意义的东西产生很大的影响......
  • 如果您收到任何错误,您将关闭套接字。然后,您将无条件地关闭它并关闭它。 (关闭实际上是多余的。) SO_ERROR 中有什么?以及 OnceCommand 是如何声明的?
  • @dubundu 这表明你的一个或多个假设是错误的。

标签: c sockets networking


【解决方案1】:

您使用 0 作为协议。这应该是什么?如果是TCP,尝试在socket调用中使用IPPROTO_TCP,即。

OnceCommand = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)

【讨论】:

  • 0 设置默认协议,即IPPROTO_TCP
  • 没错,我只是在自己的代码上尝试了 0 并且它有效 - 我应该在回答之前阅读手册页:-(顺便说一句,第一个 perror() 打印的错误与第二个相同temp 中的值是否与这些一致?我猜对 getsockopt 的调用只是调试代码。或者?Err() 也有什么重要的作用吗?你可以在 write() 之前尝试调用 setsockopt() 来查看是否它有效,例如int opt = 1; if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &amp;opt, (socklen_t) sizeof opt) &lt; 0) perror("etc");
【解决方案2】:

问题不在程序的客户端部分。可能是由于使用研华套接字库或其他服务器程序接受了客户端的连接,但没有数据可读取。当我修改服务器程序以仅通过选择接收数据时,它开始工作正常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-14
    • 2019-08-01
    • 2014-01-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多