【问题标题】:Reason for connection error in socket programming (on client side)?套接字编程中连接错误的原因(在客户端)?
【发布时间】:2019-10-04 13:26:14
【问题描述】:

我的套接字编程客户端的connect() 方法存在问题。我不确定问题出在我的代码还是我的运行方法上。我在两个单独的终端窗口中运行它——一个用于服务器(我首先运行),命令为“./server 8080”,另一个用于客户端,命令为“./client 4 8080 hello”。当我运行我的代码时,服务器程序在printf("this prints\n") 行之后的while 循环中停止。我认为这意味着它正在等待客户端连接到它。客户端程序在调用connect() 时失败,并打印出我的错误消息“连接失败”。我的代码发布在下面。

服务器代码:

#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h> 
#include <string.h> 
#include <sys/wait.h> 

#define bufsize 1024

void eatZombies(int n){
    wait3(NULL,WNOHANG,NULL); // Nom Nom 
}

int main(int argc, char *argv[]){
    int sock, length, msgsock, status;
    struct sockaddr_in server;
    pid_t id;       
    signal(SIGCHLD, &eatZombies);
    int server_fd = socket(AF_INET, SOCK_STREAM, 0);
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons(atoi(argv[1])); // this time 1st arg is port#
    if(bind(server_fd, (struct sockaddr *)&server, sizeof(server)) < 0){
        printf("Error binding the socket\n");
        exit(0);
    }

    if(listen(server_fd, SOMAXCONN) < 0){
        printf("Error listening for connections\n");
        exit(0);
    }
    char buffer[1024] = {0}; 
    char *hello = "Hello from server"; 
    int addrlen = sizeof(server);    
    while(1){
        printf("this prints\n");
        int client_fd = accept(server_fd, (struct sockaddr *)&server, (socklen_t*)&addrlen);
        printf("this doesnt\n");
        if(client_fd < 0){
            printf("Error accepting connection\n");
            exit(0);
        }
        // the next call makes a new child process that will actually handle the client.
        id = fork();
        // when id == 0, this is the child and needs to do the work for the server. 
        // when if > 0, this is the parent, and it should just loop around,
        // when id < 0, we had an error.
        if(id > 0){
            continue;
        }
        else if(id < 0){
            printf("Error\n");
            exit(0);
        }  
        read(client_fd, buffer, 1024); 
        printf("%s\n", buffer); 
        write(client_fd, hello, strlen(hello), 0); 
        printf("Hello message sent\n");
        exit(0);
    }
    return 0;
}

客户代码:

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

#define bufsize 1024

int main(argc, argv) int argc; char *argv[];{
    int sock, rval;
    struct hostent *host;
    struct sockaddr_in server;  // not a pointer
    char buf[bufsize];
    printf("%d\n", argc);
    if(argc != 4){
        printf("usage:\ntcpclient hostname port string\n\n");
        return(-1);
    }
    // look up hostname (server) using DNS
    if ((host = gethostbyname(argv[1])) == 0) {
        fprintf(stderr, "%s: unknown host\n", argv[1]); 
        return(-1);  
    }
    // Set up fields for socket to point to host and port
    bcopy(host->h_addr, &server.sin_addr, host->h_length);
    server.sin_family = AF_INET;
    server.sin_port = htons(atoi(argv[2]));
    // Create socket 
    sock = socket(AF_INET, SOCK_STREAM, 0);
    if(sock < 0){
        printf("Socket Creation Failed\n");
        exit(0);
    }
    // connect (3-way handshake)
    if(connect(sock, (struct sockaddr *)&server, sizeof(server)) < 0){ 
        printf("Connection Failed\n"); 
        exit(0); 
    } 
    // Copy the arg into buf so we can send it to the server
    strncpy(buf, argv[3], bufsize);
    // Send sentence to server
    send(sock, buf, strlen(buf), 0);
    printf("Message sent\n");
    // read response from server
    rval = read(sock, buf, bufsize);
    // print result to window
    fprintf(stdout,"%s\n", buf);
    close(sock);
}

【问题讨论】:

  • 在错误情况下将printf更改为perror。这将打印调用失败原因的错误文本。
  • 查看“写入”调用。编译器抱怨 write 需要 3 个参数。您指的是“发送”吗?
  • 代码在 Linux Mint 19 上构建/运行正常。您将什么参数传递给客户端和服务器。特别是,您是否使用“localhost”和相同的端口号?
  • @dbush 我个人更喜欢printf("something failed with error %d, (%s)", errno, strerror(errno)),结合了自定义错误信息+错误源...
  • 我的意思是“发送”。谢谢你的帮助。下面的答案建议我使用不同的命令行参数来解决问题。

标签: c++ c sockets networking


【解决方案1】:

运行./client 4 8080 hello 时,4 是主机名。你的意思是打电话给./client localhost 8080 hello

所以这只是调用应用程序的错误,而不是代码中的错误。

【讨论】:

  • 难以置信。你修好了。我真的没想到会这么容易。非常感谢!
  • 即使是 @David Franz 的这个锅,请在您的回答中添加更多解释以使其完整。
猜你喜欢
  • 1970-01-01
  • 2019-03-17
  • 1970-01-01
  • 2015-02-08
  • 1970-01-01
  • 2023-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多