【问题标题】:connect call on client side unix socket programming客户端unix套接字编程上的连接调用
【发布时间】:2023-03-03 11:49:01
【问题描述】:

我是 Unix 网络的新手,我无法理解我的代码有什么问题。我已经研究了很多,从逻辑上讲,代码应该可以工作,但我现在正在拔头发。客户端连接调用不断抛出错误 - 将 errno 设置为 22。我不明白传递连接参数的方式有什么问题。

客户端代码是:

#include <netinet/in.h>
#include <sys/select.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdint.h>
#include <strings.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

int main(int argc, char *argv[])
{

    char buffer[256];
    uint32_t
    serverip=; //ip goes here

    struct sockaddr_in clientsock;
    memset(&clientsock, 0, sizeof(clientsock));
    clientsock.sin_family = AF_INET;
    clientsock.sin_addr.s_addr = htonl(serverip);
    clientsock.sin_port = htons((unsigned short) 5000);
    socklen_t clientsocksize = sizeof(clientsock);
    int clientfd = socket(AF_INET, SOCK_STREAM, 0);
    int retval = -1;

    retval = connect(clientfd, (struct sockaddr*) &clientsock,
            sizeof(struct sockaddr_in));

    while (1)
    {
        if (retval == -1)
        {
            printf("error while connecting...\n");
            printf("error: %i\n", errno);
            retval = connect(clientfd, (struct sockaddr*) &clientsock,
                    sizeof(struct sockaddr_in));
        }
        else if (retval == 0)
        {
            printf("connection returned: %i\n", retval);
            printf("please enter data: ");
            bzero((char *) &buffer, sizeof(buffer));
            fgets(buffer, 255, stdin);
            write(clientfd, buffer, sizeof(buffer));
        }
        else
        {
            printf("error in else: %i\n", errno);

        }
    }
}

任何指导和批评将不胜感激。

【问题讨论】:

  • 他在什么时候抛出那个错误`?
  • 您使用的是 INET 套接字,而不是 unix-sockets。

标签: c sockets tcp network-programming ip


【解决方案1】:

Errno 22 是EINVAL,这意味着您传递给connect 的某些参数无效。可能的错误之一是您正在设置 sockaddr 并分配给uint32_t

uint32_t serverip=; //ip goes here
clientsock.sin_addr.s_addr = htonl(serverip);

serverip 到底是什么?你怎么得到它?通常您应该调用getaddrinfoinet_pton 将主机名或点分ip 字符串转换为sockaddr.sin_addr。例如,如果你使用getaddrinfo,你可以使用它直接返回的sockaddr

connect(clientfd, res->ai_addr, res->ai_addrlen);

或者如果你使用inet_pton

inet_pton(AF_INET, ipstr, &clientsock.sin_addr.s_addr);

另外,最好检查socket 返回值是否有任何错误:

int clientfd = socket(AF_INET, SOCK_STREAM, 0);
if (clientfd < 0) {
      // error
      exit(1);
}

【讨论】:

  • serverip 是服务器的 ip 地址 - 我现在只是硬编码以测试我是否可以成功连接到服务器。我使用 uint32_t 因为这是地址存储在 struct in_addr 中的类型,根据:linux.die.net/man/7/ip。我更改了它并尝试使用 inet_pton 但我仍然遇到同样的错误。
  • 什么是硬编码值?它可能会起作用,因为您还为此调用了htonl
  • @AliSyed 请发布您收到的确切错误以及您收到错误的位置?
  • Connect 返回 -1,然后执行以下代码: if (retval == -1) { printf("error: %i\n", errno); retval = connect(clientfd, (struct sockaddr*) &clientsock, sizeof(struct sockaddr_in)); }.
  • 行“连接时出错..\n”和“错误:22”行迭代打印到屏幕然后由于while循环
猜你喜欢
  • 2018-03-18
  • 2015-02-08
  • 2012-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多