本地主机的 TCP socket 连接被拒绝

3
我正在尝试在本地主机上制作一个客户端/服务器程序,但客户端无法连接到服务器,我不知道我做错了什么。
我已经尝试调试程序,所有参数似乎都没问题。服务器已绑定(bind),连接(connect),监听(listen)和接受(accept)。
使用客户端代码时,我得到了“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 !");
    }
}

2
知道吗,端口号1024以下是保留的,非特权应用程序无法使用?为什么不检查服务器应用程序中的错误? - Some programmer dude
在服务器代码中,您还有两个未定义行为的情况,都与size变量有关?首先,类型是错误的,应该是socklen_t。其次,在调用accept之前,每次循环都需要初始化它。例如,请参阅accept手册页面 - Some programmer dude
@JachimPleborg 我已经尝试了1025,但也没有成功。 - Jesús Martín Berlanga
顺便提一下,当 connect 失败时,尝试打印出 errno 的值以查看实际的错误。您可以使用 strerror 从错误代码中获取可打印的字符串。 - Some programmer dude
@JachimPleborg,我已经按照你说的更新了服务器并加入了 socklen_t,但仍然无法正常工作。 - Jesús Martín Berlanga
@JachimPleborg 我遇到了“connect: Invalid argument”错误。奇怪的是,我有另一个程序,在那里我基本上做了同样的事情,但我得到了“connect: Connection refused”的错误提示。 - Jesús Martín Berlanga
2个回答

6

你的示例代码中可能有拼写错误,或者

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

括号使用不正确。目前你将使用0作为socklen_t addrlen参数调用connect函数。应该更改为

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

3
这个问答涉及到了我的“debug失败-没有将复合表达式简化为具有中间变量的简单行”的书签列表。 - Martin James

0

在 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测试服务器:

telnet 127.0.0.1 1025


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接