【问题标题】:c TCP socket connection refused for localhostc TCP 套接字连接拒绝本地主机
【发布时间】:2016-07-09 07:18:11
【问题描述】:

我正在尝试在 localhost 中创建客户端/服务器程序,但客户端无法连接到服务器,我不知道我做错了什么。

我已经尝试调试程序,所有参数似乎都可以。服务器确实绑定、连接、侦听和接受。

使用客户端代码会出现 connect: Invalid argument 错误。客户端(我用./client localhost从控制台调用客户端):

#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>

int main(int argc, char * argv[])
{
    int cd;
    struct hostent *hp;
    struct sockaddr_in s_ain;
    unsigned char byte;

    hp = gethostbyname(argv[1]);
    bzero((char *)&s_ain, sizeof(s_ain));
    s_ain.sin_family = AF_INET;
    memcpy(&(s_ain.sin_addr),  hp->h_addr, hp->h_length);
    s_ain.sin_port = htons(1025);

    cd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if( connect(cd, (struct sockaddr*) &s_ain, sizeof(s_ain) == -1) ) {
        fprintf(stderr, "connect: %s\n", strerror(errno));
        return -1;
    }       

    printf("%s\n", "IT WORKS!");
    close(cd);
    return 0;
}

服务器:

#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <stdio.h>

int main(void)
{
    int sd, cd;
    socklen_t size;     
    unsigned char byte;
    struct sockaddr_in s_ain, c_ain;    

    sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    bzero((char *)&s_ain, sizeof(s_ain));
    s_ain.sin_family = AF_INET;s_ain.sin_family = AF_INET;
    s_ain.sin_addr.s_addr = INADDR_ANY;
    s_ain.sin_port = htons(1025);

    if(bind(sd, (struct sockaddr *)&s_ain, sizeof(s_ain)) == -1) {
        fprintf(stderr, "%s\n", "err bind");
        return -1;
    }

    if(listen(sd, 5) == -1) {
        fprintf(stderr, "%s\n", "err listen");
        return -1;
    }

    while(1) {
        size = sizeof(c_ain);
        cd = accept(sd, (struct sockaddr *)&c_ain, &size);
        printf("%s\n", "IT WORKS !");
    }
}

【问题讨论】:

  • 你知道 1024以下的端口号是保留的,不能被非特权应用程序使用吗?为什么不检查服务器应用程序中的错误?
  • 您在服务器代码中也有两个 的未定义行为 情况,都与size 变量有关?首先类型不对,应该是socklen_t。其次,每次在循环中调用accept 之前都需要对其进行初始化。参见例如this accept manual page.
  • @JachimPleborg 我试过 1025 也没有运气。
  • 顺便说一句,当connect 失败时,尝试打印出errno 的值,看看你实际得到了什么错误。您可以使用strerror 从错误代码中获取可打印的字符串。
  • @JachimPleborg 我已经用socklen_t 和你所说的更新了服务器,但仍然无法正常工作。

标签: c sockets tcp localhost client-server


【解决方案1】:

您的示例中有错字,或者

if( connect(cd, (struct sockaddr*) &s_ain, sizeof(s_ain) == -1) ) {
    fprintf(stderr, "%s\n", "err connect");
    return -1;
}

括号错误。目前,您将使用socklen_t addrlen 作为0 调用connect。它应该是

if( connect(cd, (struct sockaddr*) &s_ain, sizeof(s_ain)) == -1) {
    fprintf(stderr, "%s\n", "err connect");
    return -1;
}

【讨论】:

  • ...这个问答进入了我的“调试失败 - 没有将复合表达式简化为带有中间变量”书签列表的更简单的行。
【解决方案2】:

server.c 中的一些修复

#include <netinet/in.h> // fix
#include <sys/types.h>
#include <netdb.h>
#include <string.h>
#include <stdio.h>

int main(void)
{
    int sd, cd;
    unsigned char byte;
    struct sockaddr_in c_ain;

    sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    bzero((char *)&c_ain, sizeof(c_ain));
    c_ain.sin_family = AF_INET;
    c_ain.sin_addr.s_addr = INADDR_ANY;
    c_ain.sin_port = htons(1025);

    bind(sd, (struct sockaddr *)&c_ain, sizeof(c_ain));
    listen(sd, 5);

    struct sockaddr_in t_ain;
    while(1) {
       int size = sizeof(t_ain); // < fix
       cd = accept(sd, (struct sockaddr *)&t_ain, (socklen_t*)&size); // < fix
       printf("%s\n", "IT WORKS !");
    }
}

也可以使用 telnet 来测试服务器:

远程登录 127.0.0.1 1025

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-25
    • 1970-01-01
    • 2015-07-30
    • 1970-01-01
    • 1970-01-01
    • 2013-07-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多