连接错误:套接字处的参数无效

时间:2014-07-04 16:05:27

标签: c++ sockets

我有这段代码

Server:
//"sock" has already been created with no problem and binding as well

void Connection::bind_connection(int port){
    cout << "Port " << port << endl;
    server.sin_family = AF_INET ;
    server.sin_addr.s_addr = htonl(INADDR_ANY);
    server.sin_port = htons(port);
    /* Bind socket to address */
    struct sockaddr *serverptr = ( struct sockaddr *) &server;
    if ( bind ( sock , serverptr , sizeof(server) ) < 0) {
        perror("Binding error"); exit(BE);
    }
    cout << "Server binding completed!" << endl;
}    

struct sockaddr_in client ;
socklen_t clientlen ;
struct sockaddr * clientptr =( struct sockaddr *) &client ;
if ( listen (sock , MAX_CONNECTIONS) < 0) {perror("listening error"); exit(LE);}
cout << "Listening for connections to port " << port << endl;
while (1) {
    /* accept connection */
    if (( newsock = accept ( sock , clientptr , &clientlen ) ) < 0) {
        perror("Accepting error"); cout << "Errno = " << errno << endl; exit(AE);
    }
    //Code
    ....
}

Client:
//struct sockaddr_in server; <--- declared as data member of class "Connection"
//"sock" has already been created with no problem
void Connection::do_connect(){
    struct sockaddr *serverptr = ( struct sockaddr *) &server;
    if ( connect ( sock , serverptr , sizeof (server) ) < 0)
         perror("client connect"); exit(CE);
    cout << "Client connecting to the server" << endl;
}

我收到了上述消息。大多数代码都是从课程幻灯片中复制的,但是根据我的需要进行了修改。谷歌搜索问题似乎我在系统调用中给出了错误的大小。知道问题究竟在哪里?提前谢谢。

3 个答案:

答案 0 :(得分:2)

您没有初始化clientlen

socklen_t clientlen = sizeof(client);

通过valgrind运行代码,您可以在将来发现类似的问题。

答案 1 :(得分:2)

这些行总是退出:

if ( connect ( sock , serverptr , sizeof (server) ) < 0)
     perror("client connect"); exit(CE);

您可能会开始考虑使用不同的缩进方案。通常是每行不使用多于一个语句的那个​​。

对于上面的代码,像indent这样的工具会将其格式化为:

if (connect (sock, serverptr, sizeof (server)) < 0)
  perror("client connect");
exit(CE);

这种格式使编程错误显而易见。

答案 2 :(得分:0)

As already indicated,您似乎没有正确初始化变量。您没有展示如何初始化sockaddr_in结构,这可能是罪魁祸首。指定bind()connect()地址的相对简单方法是使用getaddrinfo() / freeaddrinfo()From the documentation

  

<强>概要

      int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res);
      void freeaddrinfo(struct addrinfo *res);

   的描述

  给定 node service ,它们标识Internet主机和服务,getaddrinfo()返回一个或多个addrinfo结构,每个结构包含一个可以的Internet地址。在致电bind(2)connect(2)时指定。 ...

  freeaddrinfo()函数释放为动态分配的链接列表 res 分配的内存。

作为一个简单示例,这是一个可以连接到由格式为<servername>:<port>的字符串指定的服务器的函数:

int connect_tcp (std::string hostspec) {
    struct addrinfo hints = { .ai_flags = AI_NUMERICSERV };
    struct addrinfo *res = 0;
    std::istringstream ss(hostspec);
    std::string node, service;
    int sock = -1;
    std::getline(ss, node, ':');
    std::getline(ss, service, ':');
    getaddrinfo(node.c_str(), service.c_str(), &hints, &res);
    for (struct addrinfo *rp = res; rp != 0; rp = rp->ai_next) {
        if (rp->ai_socktype != SOCK_STREAM) continue;
        int sock = socket(rp->ai_family, SOCK_STREAM, 0);
        if (sock == -1) continue;
        if (connect(sock, rp->ai_addr, rp->ai_addrlen) != -1)
            break;
        close(sock);
        sock = -1;
    }
    freeaddrinfo(res);
    if (sock == -1) errno = EHOSTDOWN;
    return sock;
}