套接字:协议不支持的绑定地址

时间:2014-01-28 17:03:46

标签: linux sockets gcc

简单TCP回送服务器的源代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define MAX_BUFFER  1024
#define PORT       20000

int main()
{
  int lsock,csock, ret, in , i;
  int yes = 1;
  char buffer[MAX_BUFFER];
  char* c;
  struct addrinfo hints, *servinfo, *p;
  struct sockaddr_in servaddr;
  struct sockaddr_in cliaddr; // connector's address information

  if((lsock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))<0){
      perror("socket");
      exit(0);
  }

  bzero(&servaddr,sizeof(servaddr));
  servaddr.sin_family = AF_INET;
  servaddr.sin_port = htons(PORT);
  servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

  if(bind(lsock,(struct sockaddr*)&servaddr,sizeof(servaddr))<0) {
            close(lsock);
            perror("server: bind");
            return -1;
  }

  if(listen(lsock,5)<0){
           perror("listen");
           exit(0);
  }else{     
           printf("Server listening on port %i\n",PORT);
  }

  while(1){
     int len = sizeof(cliaddr);
     bzero(&cliaddr,len);

     if(csock = accept(lsock,(struct sockaddr*)&cliaddr,&len)<0){
           perror("accept");
           exit(0);
     } 

     printf("New client connected....\n");

     in = recv(csock,(void*)&buffer,sizeof(buffer),0);

     if(in <0){
            perror("recvmsg");
            close(csock);
            exit(0);
     }else if(in==0){    
           printf("client disconnected\n");
           close(csock);
     }else{

       if(send(csock,(void*)buffer,sizeof(buffer),0)<0){
        perror("sendmsg");
            close(csock);
       }
     }
  }

  return 0;
}

代码编译得很好。但每当我执行输出文件时,我都会收到以下错误消息:

server: bind: Address family not supported by protocol

我使用netcat命令测试网络接口,包括监听和连接到loopback接口,因此它似乎不是内核问题。但无论我尝试绑定到哪个地址都会返回相同的错误消息。我甚至说GCC的一个错误报告在大约7年前提到了这个特定的错误,所以我显然不是第一个遇到这个问题的人(那是与之前版本的GCC有关)。我有GCC版本4.7.3。有没有人拥有更新的glibc库的4.8.X版本?如果是这样,我想知道这个错误是否仍然存在。

1 个答案:

答案 0 :(得分:0)

所以我通过添加标题来修改标题(它具有套接字函数的实际系统调用号)。并将先前使用原型(链接到Glibc库)实现的“绑定”功能替换为:

extern int bind(int sockfd,  __SOCKADDR_ARG addr, socklen_t addrlen)__THROW;

使用实际实现,使用__NR_syscall表中的bind值进行直接系统调用:

int bind(int sockfd,  __SOCKADDR_ARG addr, socklen_t addrlen)
{

     _syscall3(int,bind,int,sockfd,__SOCKADDR_ARG,addr,socklen_t,addrlen)


} __THROW;

编译和执行输出文件后的输出。

Server listening on port 20000

<强> w00t!w00t!