【问题标题】:C sockets (Linux) won't connectC 套接字 (Linux) 无法连接
【发布时间】:2018-01-03 14:42:40
【问题描述】:

最近我一直在尝试使用 C 套接字做很多事情,因为它是我将来需要使用的一种语言。但是我遇到了这个我无法解决的问题。我同时制作了客户端和服务器 - 不幸的是,这两个二进制文件拒绝相互连接。我的意思是,当我在同一台机器上运行服务器二进制文件和客户端二进制文件时,我没有收到任何错误,但也没有连接。有任何想法吗?这是代码!

(Ubuntu,使用 gcc 编译的 C 代码、服务器和客户端代码在同一台机器的 2 个不同终端中运行。)

服务器.c:

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h> 
    #include <string.h>
    #include <sys/socket.h>
    #include <arpa/inet.h> //inet_aton(), inet_ntoa() etc
    #include <sys/types.h>
    #include <netinet/in.h>

    #define PORT 8000
    #define ERROR perror("Something went wrong! => ");
    #define BUFFERSIZE 256
    int main()
    {
        int sockfd, client_socketfd; 
        int bytes_sent; 
        socklen_t sin_size;
        struct sockaddr_in server_addr;
        struct sockaddr_in connectedClient_addr;
        char message[BUFFERSIZE] = "Welcome to the server!";

        if((sockfd = socket(PF_INET, SOCK_STREAM ,0)) == -1) {
            ERROR;
            exit(-1);
        }

        server_addr.sin_family = AF_INET;
        server_addr.sin_port   = htons(PORT);
        server_addr.sin_addr.s_addr = INADDR_ANY; //Subject to change


        if((bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr))) == -1) {
            ERROR;
            exit(-2);
        }


        if((listen(sockfd, 5)) == -1) {
            ERROR;
            exit(-3);
        }   

        int addrlen = sizeof(connectedClient_addr);
        if((client_socketfd = accept(sockfd, (struct sockaddr *)&connectedClient_addr, (socklen_t*)&addrlen)) == -1){
            ERROR;
            exit(-4);
        }   

        printf("Got a connection from: %s at port: %d" , inet_ntoa(connectedClient_addr.sin_addr), PORT);

        if((send(sockfd, &message, BUFFERSIZE, 0)) == -1) {
             ERROR;
             exit(-5);
        }

         close(sockfd);
         close(client_socketfd);

        return 0;
    }

--

客户端.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>


#define PORT 8000
#define ERROR perror("Something went wrong! =>");
#define BUFFERSIZE 256
int main()
{
    int sockfd;
    struct sockaddr_in client_addr;
    char message[BUFFERSIZE] = "Successfully connected!";
    int bytes_received, bytes_sent;
    char buffer[BUFFERSIZE];


    if((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
        ERROR;
        exit(-1);
    }


    client_addr.sin_family = AF_INET;
    client_addr.sin_port   = htons(PORT);
    client_addr.sin_addr.s_addr = INADDR_ANY;


    if((connect(sockfd, (struct sockaddr*)&client_addr, sizeof(client_addr))) == -1) {
        ERROR;
        exit(-2);
    }

    if((bytes_received = recv(sockfd, &buffer, BUFFERSIZE, 0)) == -1) {
        ERROR;
        exit(-3);
    }

    printf("Received %d bytes:\n" , bytes_received);
    printf("%s", buffer);

    close(sockfd);

    return 0;
}

【问题讨论】:

  • 对于connect 调用,您必须指定一个特定地址
  • 在这一行,在客户端代码中:client_addr.sin_addr.s_addr = INADDR_ANY;,您尝试将客户端连接到任何地址。您需要指定要连接的IP地址
  • @Someprogrammerdude “特定地址”是什么意思?你能提供一个连接函数的例子吗?
  • 现在是时候阅读一些我早该告诉你的东西了:How to debug small programs,作者是 Eric Lippert。阅读那篇文章,了解如何使用调试器。然后使用调试器单步执行客户端和服务器。这样你就会看到真正发生了什么。
  • @RamonSS:客户端已成功连接到服务器(您只是没有在客户端记录它),但服务器中有一个错误,它在调用 send(sockfd, ...) 时应该打电话给send(client_socketfd, ...)。您将问候消息发送到错误的套接字描述符,因此客户端无法读取任何内容,并且 recv() 最终被阻塞,直到服务器关闭连接。

标签: c sockets network-programming


【解决方案1】:

回答: 问题是我在 server.c 中的 send() 函数内提供了服务器套接字,而不是客户端套接字。因此,代码可以正常工作,但行为不正确。归功于RemyLebeauin the comments,他指出了这一点并为我节省了无数小时的挣扎。

【讨论】:

  • 代码不可能“正常工作”。您一定没有检查send() 函数的错误。很明显,要么这不是真正的代码,要么你没有报告所有的症状。
  • @EJP 我没有收到编译器警告或问题。我只是忘了指定正确的套接字。该程序运行正常,我是如何告诉它的。不是我想要的。如果您认为我应该修改最终答案,请提交修改请求,我很乐意接受。
猜你喜欢
  • 1970-01-01
  • 2014-03-01
  • 2021-10-28
  • 2018-03-12
  • 2018-11-29
  • 1970-01-01
  • 2011-10-03
  • 2021-05-10
  • 1970-01-01
相关资源
最近更新 更多