【问题标题】:linux socket accept can't been blockedlinux socket接受不能被阻止
【发布时间】:2013-03-16 13:14:29
【问题描述】:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <sys/types.h>
    #include <sys/socket.h>

    int main()
    {
    int server_sockfd,client_sockfd;
    int server_len,client_len;
    struct sockaddr_in server_address;
    struct sockaddr_in client_address;

创建一个新的套接字

    unlink("server_socket");
    server_sockfd=socket(AF_INET,SOCK_STREAM,0);

给它命名

    server_address.sin_family=AF_INET;
    server_address.sin_addr.s_addr=htonl(INADDR_ANY);
    server_address.sin_port=htons(9734);
    server_len=sizeof(server_address);
    bind(server_sockfd,(struct sockaddr *)&server_address,server_len);

设置块

    int flags=fcntl(server_sockfd,F_GETFL,0);
    if(flags&O_NONBLOCK==1){
       printf("NONBLOCK");
    }else{
       printf("BLOCK");
    }
    flags=flags&~O_NONBLOCK;
    fcntl(server_sockfd,F_SETFL,flags);
    if(flags&O_NONBLOCK==1){
       printf("NONBLOCK");
    }else{
       printf("BLOCK");
    }

    listen(server_sockfd,5);
    while(1){
       char ch;
       printf("server waiting\n");
       client_len=sizeof(client_address);
       client_sockfd=
          accept(server_sockfd,(struct sockaddr*)&client_sockfd,&client_len);

第一次被屏蔽

      read(client_sockfd,&ch,1);
      ch++;
      write(client_sockfd,&ch,1);
      close(client_sockfd);
   }
}

当客户端第一次连接时,我工作,但下一个将不工作

【问题讨论】:

  • client_sockfd=accept 检查client_socket的值。也可以是 -1 -> 检查 errno。还要检查 read() 的返回值
  • socket 默认是阻塞的,所以不需要 fcntl 调用。 unlink 电话也完全没有必要。其次,您必须检查可能失败的bind 的返回值(以及listensocket 等...)。

标签: linux sockets connection block


【解决方案1】:

client_addressclient_sockfd 之间可能会出现不匹配。

man page of accept() 说:

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

The addrlen argument is a value-result argument: the caller must initialize it to
contain the size (in bytes) of the structure pointed to by addr; on return it
will contain the actual size of the peer address.

试试:

client_sockfd=
   accept( server_sockfd, (struct sockaddr*)&client_address, &client_len );

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-22
    相关资源
    最近更新 更多