【问题标题】:Unable to receive TCP data on particular IP无法接收特定 IP 上的 TCP 数据
【发布时间】:2016-12-06 12:41:18
【问题描述】:

我正在尝试在 Linux 系统上用 C 语言实现 TCP 客户端、服务器程序。这是我的代码。

客户端源代码:

#include <stdlib.h>
#include <stdio.h>

#include <sys/types.h>
#include <sys/socket.h>

#include <netinet/in.h>
#include <arpa/inet.h>

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

   // Create socket
   int client_socket;
   client_socket = socket(AF_INET, SOCK_STREAM, 0);

   // Set - Up Server Address
   struct sockaddr_in server_address;
   server_address.sin_family = AF_INET;
   server_address.sin_port = htons(8001);
   inet_aton(address, &server_address.sin_addr.s_addr);

   // Connect to the server 
   int connect_stat;
   connect_stat = connect(client_socket, (struct sockaddr *) &server_address, sizeof(server_address));
   if(connect_stat == -1)
        printf("Not Connected\n");
   else
        printf(" Connected \n");
   // Recieve from server
   char response[256];
   recv(client_socket, &server_address, sizeof(server_address), 0);

   // Printing the Response data
   printf("Data Recieved : %s\n",response);

   // Destroy the socket
   close(client_socket);

   return 0;
}

服务器源代码:

#include <stdio.h>
#include <stdlib.h>

#include <sys/types.h>
#include <sys/socket.h>

#include <netinet/in.h>
#include <arpa/inet.h>

int main(int argc, char *argv[])
{
    // Address
    char *address;
    address = argv[1];

    // Create message to send
    char message[256] = "Connection Established";

    // Create server socket
    int server_socket;
    server_socket = socket(AF_INET, SOCK_STREAM, 0);

    // Set - Up Server Address
    struct sockaddr_in server_address;
    server_address.sin_family = AF_INET;
    server_address.sin_port = htons(8001);
    inet_aton(address, &server_address.sin_addr.s_addr);

    // Bind it to an IP and PORT
    bind(server_socket, (struct sockaddr *) &server_address, sizeof(server_address));

    // Start listenting on address
    listen(server_socket, 5);

    // Start accepting the clients;
    int client_socket;
    client_socket = accept(server_socket, NULL, NULL);

    // Send some data back to client
    send(client_socket, message, sizeof(message), 0);

    // Close the socket
    close(server_socket);
    close(client_socket); 

    return 0;
}

将像 192.168.1.xxx 这样的 IP 传递给客户端和服务器时,服务器开始等待客户端,但客户端始终显示未连接,因此没有收到数据。

客户端输出:

root@kali:/home/mayank/Desktop/tcp_chat# ./tcp_client 192.168.1.111
Not Connected
Data Recieved : 

但是如果我使用 INADDR_ANY 而不是特定的 IP,它可以工作。我知道 INADDR_ANY 基本上意味着它绑定到所有 IP 地址,但为什么它没有绑定到我想要的特定 IP 地址。任何建议,我错了。

【问题讨论】:

  • 打印“未连接”时检查errno
  • 在我的程序中包含 errno.h 后,我得到了以下输出 root@kali:/home/mayank/Desktop/tcp_chat# ./tcp_Client 192.168.1.100 Not Connected Errno : 88 Data Recieved :
  • 错误代码 88 是 ENOTSOCK,这意味着您正在对不是有效套接字的文件描述符调用套接字函数。您的大部分代码根本没有执行任何错误处理,例如确保 socket() 没有返回值

标签: sockets tcp server client systypes.h


【解决方案1】:

除了inet_aton(),你也可以使用

server_address.sin_addr.s_addr = inet_addr("IP address");

并在每个函数之后使用perror(),例如

client_socket = socket(...);
if (client_socket == -1)
    perror("socket");

【讨论】:

  • 错误输出显示“非套接字上的套接字操作”,我什至用 inet_addr() 替换了 inet_aton 但同样的问题仍然存在
  • 在客户端,address 未初始化。
【解决方案2】:

除了connect() 调用之外,您没有进行任何错误检查。例如,您收到 ENOTSOCK 错误,因为您没有检查 socket() 是成功还是失败。

除此之外,在客户端,此声明:

inet_aton(address, &server_address.sin_addr.s_addr);

应该改为:

inet_aton(address, &server_address.sin_addr);

inet_aton() 需要一个指向 struct in_addr 的指针,但您传递给它的是一个指向 uint32_t 的指针。事实上,原来的代码甚至不应该因此而编译。

但是,更重要的是,您的 address 变量未初始化,因此您将错误的内存指针传递给 inet_aton(),并且没有检查其返回值是否失败。

即使您可以连接到服务器,您也将错误的输出缓冲区传递给recv(),因此您最终会将垃圾写入控制台。

试试这个:

#include <stdlib.h>
#include <stdio.h>

#include <sys/types.h>
#include <sys/socket.h>

#include <netinet/in.h>
#include <arpa/inet.h>

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        printf("usage: %s <IPv4 address>\n", argv[0]);
        return 0;
    }

    // Set - Up Server Address
    struct sockaddr_in server_address = {0};
    server_address.sin_family = AF_INET;
    server_address.sin_port = htons(8001);
    if (inet_aton(argv[1], &server_address.sin_addr) != 0)
    {
        printf("invalid IPv4 address specified\n");
        return 0;
    }

    // Create socket
    int client_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (client_socket == -1)
    {
        perror("socket() failed");
        return 0;
    }

    // Connect to the server 
    if (connect(client_socket, (struct sockaddr *) &server_address, sizeof(server_address)) == -1)
    {
        perror("Not Connected");
    }
    else
    {
        printf("Connected\n");

        // Receive from server
        char response[256];
        int numRecvd = recv(client_socket, response, sizeof(response), 0);

        // Printing the Response data
        if (numRecvd == -1)
            perror("recv() failed");
        else if (numRecvd == 0)
            printf("Disconnected by server\n");
        else
            printf("Data Received: [%d] %.*s\n", numRecvd, numRecvd, response);
    }

    // Destroy the socket
    close(client_socket);

    return 0;
}

#include <netinet/in.h>
#include <arpa/inet.h>

int main(int argc, char *argv[])
{
    // Set - Up Server Address
    struct sockaddr_in server_address = {0};
    server_address.sin_family = AF_INET;
    server_address.sin_port = htons(8001);
    if (argc >= 2)
    {
        if (inet_aton(argv[1], &server_address.sin_addr) != 0)
        {
            printf("invalid IPv4 address specified\n");
            return 0;
        }
    }
    else
        server_address.sin_addr.s_addr = INADDR_ANY;

    // Create message to send
    char message[256] = "Connection Established";

    // Create server socket
    int server_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (server_socket == -1)
    {
        perror("socket() failed");
        return 0;
    }

    // Bind it to an IP and PORT
    if (bind(server_socket, (struct sockaddr *) &server_address, sizeof(server_address)) == -1)
    {
        perror("bind() failed");
    }

    // Start listenting on address
    else if (listen(server_socket, 5) == -1)
    {
        perror("listen() failed");
    }

    // Start accepting the clients
    else
    {
        int client_socket = accept(server_socket, NULL, 0);
        if (client_socket == -1)
        {
            perror("accept() failed");
        }
        else
        {
            // Send some data back to client
            int numSent = send(client_socket, message, sizeof(message), 0);
            if (numSent == -1)
                perror("send() failed");
            else
                printf("Data Sent: [%d] %.*s\n", numSent, numSent, message);

            // Close the socket
            close(client_socket); 
        }
    }

    // Destroy the socket
    close(server_socket);

    return 0;
}

【讨论】:

    猜你喜欢
    • 2011-09-13
    • 2020-08-16
    • 2012-08-09
    • 2012-06-09
    • 2020-09-18
    • 2014-09-06
    • 1970-01-01
    • 2013-06-20
    相关资源
    最近更新 更多