1
  1. 客户

事实上,我的客户端不会接收和处理从服务器发送的数据,只是连接到我的服务器。

    int netif_msg_client_socket_create(char *sockpath)
    {

        int addrlen, retval;
        int sockfd;
        struct sockaddr_un serv;

        sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
        if(sockfd < 0) {
    PR_ERROR(NETIF_MSG_M, " fatal failure, client msg socket, error is %s, %s %u\n", strerror(errno), __FILE__, __LINE__);
            return -1;
       }

       /* Make client socket. */
       memset (&serv, 0, sizeof (struct sockaddr_un));
       serv.sun_family = AF_UNIX;
       strncpy (serv.sun_path, sockpath, strlen(sockpath));

       addrlen = sizeof (serv.sun_family) + strlen(serv.sun_path);

       retval = connect(sockfd, (struct sockaddr*)&serv, addrlen);
       if(retval < 0)
       {
            PR_ERROR(NETIF_MSG_M, " fatal failure, client msg connect, error is %s, %s %u\n", strerror(errno), __FILE__, __LINE__);
            close(sockfd);
            return -1;
       }

       fcntl(sockfd, F_SETFL, O_NONBLOCK);

       return sockfd;
    }

2.服务器

但是我的服务器会尝试不断地向客户端发送一些数据。

    int netif_msg_server_socket_create(char *sockpath)
    {

        int addrlen, retval;
        int sockfd;
        struct sockaddr_un serv;

        /* First of all, unlink existing socket */
        unlink (sockpath);

        sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
        if(sockfd < 0)
            return -1;

        fcntl(sockfd, F_SETFL, O_NONBLOCK);

        /* Make server socket. */
        memset (&serv, 0, sizeof (struct sockaddr_un));
        serv.sun_family = AF_UNIX;
        strncpy (serv.sun_path, sockpath, sizeof(serv.sun_path)-1);

        addrlen = sizeof (serv.sun_family) + strlen(serv.sun_path);
        //printf("sizeof(serv) == %d, addrlen == %d.\r\n", sizeof(serv), addrlen);

        retval = bind (sockfd, (struct sockaddr *) &serv, addrlen);
        if (retval < 0)
        {
            close (sockfd); /* Avoid sd leak. */
            return -1;
        }

        retval = listen (sockfd, 20);
        if (retval < 0)
        {
            close (sockfd); /* Avoid sd leak. */
            return -1;
        }

        return sockfd;
    }
  1. 我的服务器使用 select 并成功接受来自我的客户端的连接。
  2. 在我的服务器发送 412 个数据包(每个 96 字节)后,服务器似乎在发送时休眠。

关键代码:

    printf("Try to send packet(%d bytes) to clientfd %d.\n", MSGCB_DLEN(msgcb), client->acpt_fd);

    retval = send(client->acpt_fd, msgcb->data_ptr, MSGCB_DLEN(msgcb), 0);
    if(retval != MSGCB_DLEN(msgcb))
    {
        printf("Send netif notify msg failed[%d].\n", retval);
    } else {
    printf("Send netif notify msg succeeded.\n");
    }

在向我的客户端发送 412 个数据包并输出“尝试到 ...”后,没有任何反应,“...失败”和“...成功”都没有输出。

  1. 我使用 getsockopt 来获取 SO_RCVBUF 和 SO_SNDBUF,它们每个都有大约 100000Bytes。

  2. 我不知道为什么,需要你的帮助,谢谢!

4

2 回答 2

5

如果您希望连接到客户端的服务器套接字是非阻塞的,那么您必须专门将返回的新套接字设置为accept()非阻塞。您的代码仅将侦听套接字设置为非阻塞。

于 2013-05-31T03:56:26.757 回答
1

send您可以使用MSG_DONTWAIT最后一个参数中的标志执行非阻塞 I/O 。

    retval = send(client->acpt_fd, msgcb->data_ptr, MSGCB_DLEN(msgcb),
                  MSG_DONTWAIT);

执行非阻塞 I/O 时,您需要检测返回值何时指示您重试操作。

    if (retval < 0) {
        if (errno == EAGAIN) {
            /* ... handle retry of send laster when it is ready ... */
        } else {
            /* ... other error value cases */
        }
    }
于 2013-05-31T06:36:06.207 回答