套接字:连接失败,连接被拒绝

时间:2018-05-21 17:04:13

标签: c sockets

我有一个用c编写的套接字应用程序,我在linux上执行,但是当我执行服务器(./server)时,我收到以下错误:

  

连接失败,连接被拒绝。

以下是代码:

server.c

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

#define DEFAULT_PORT 8080

void error(char* message){
    perror(message);
    exit(EXIT_FAILURE);
}

void handler_client(void){
}

int main(int argc , char **argv[]){
    int server_fd;
    int new_socket;
    int valread;

    struct sockaddr_in address;
    int opt = 1;
    int addrlen = sizeof(address);
    char buffer[1024] = {0};
    char *hello = "Hello, I'm server";

    if((server_fd = socket(AF_INET, SOCK_STREAM , 0)) == 0){
        error("socket failed");
    }

    if(setsockopt(server_fd , SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT , &opt , sizeof(opt))){
        error("setsockertopt");
    }

    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(DEFAULT_PORT);

    if(bind(server_fd , (struct sockaddr *)&address, sizeof(address) ) < 0){
        error("bind failure");
    }

    if(listen(server_fd , 3) < 0){
        error("listen");
    }

    if((new_socket = accept(server_fd , (struct sockaddr *)&address , (socklen_t *)&addrlen)) < 0){
        error("accept");
    }

    valread = read( new_socket , buffer , 1024);
    printf(" message from client : %s \n",buffer);
    send(new_socket , hello , strlen(hello) , 0);
    printf("Hello message sent \n");
    return 0;

 }

client.c

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

#define DEFAULT_PORT  8080
#define BUFFER_SIZE  1024

void error(char* message){
    perror(message);
    exit(EXIT_FAILURE);
}

int main(int argc , char** argv){
    struct sockaddr_in address;
    int sock = 0;
    int valread;
    struct sockaddr_in serv_addr;
    char message[BUFFER_SIZE] = {0};

    char buffer[BUFFER_SIZE] = {0};

    if((sock = socket(AF_INET , SOCK_STREAM , 0)) < 0){
        error("Sockert Creation fails");
    }

    memset(&serv_addr , '0' , sizeof(serv_addr));

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(DEFAULT_PORT);

    if(inet_pton(AF_INET , "127.0.0.1" , &serv_addr.sin_addr) <= 0){
        error("Invalid address / Address not supported");
    }

    if(connect(sock , (struct sockaddr *)&serv_addr , sizeof(serv_addr) ) < 0){
        error("connection failed");
    }

    printf("enter your message : ");

    fgets(message , BUFFER_SIZE-1 , stdin);

    send(sock , message , strlen(message) , 0);
    printf("Hello message sent\n");
    valread = read(sock , buffer , BUFFER_SIZE);
    printf("response from buffer : %s\n",buffer);
    return 0;
}

1 个答案:

答案 0 :(得分:0)

“连接被拒绝”错误意味着您正在尝试连接到服务器IP:端口:

  1. 无法聆听

  2. 在其待办事项

  3. 中有太多待处理的客户端连接
  4. 被防火墙/路由器/防病毒软件阻止。

  5. 客户端无法区分导致错误的条件。它所能做的只是稍后再试,并在一段时间后放弃。

    由于您的客户端正在尝试连接到127.0.0.1,因此客户端和服务器必须在同一台计算机上运行。您将无法跨机器边界连接,并且包括主机/客户端系统之间的VM边界。

    话虽如此,我看到你的代码中出现了一些错误,但没有一个错误导致连接错误。

    服务器端:

    1. socket()出错时返回-1,而不是0。

      //if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0){
      if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
      
    2. 您无法使用setsockopt()一次设置多个套接字选项,您必须通过单独调用setsockopt()来单独设置它们。

      //setsockopt(server_fd , SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt));
      setsockopt(server_fd , SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
      setsockopt(server_fd , SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt));
      
    3. 客户方:

      1. 您正在使用serv_addr字符而不是'0'个字符填充0

        //memset(&serv_addr , '0' , sizeof(serv_addr));
        memset(&serv_addr, 0, sizeof(serv_addr));
        
      2. 双方都没有对send()进行任何错误处理。但更重要的是,您没有在发送中包含消息的空终止符,因此对等方无法知道何时到达消息的结尾。 TCP是一种流式传输,因此您需要在数据协议中构建消息。在发送消息之前发送消息的长度。或者在消息之后发送一个唯一的终止符。然后,对等方可以在读取消息之前读取长度,或者读取直到达到终结符。

        send()read()都返回实际发送/接收的字节数,这可以(通常是)比请求的字节少。您需要在循环中调用它们以确保发送/接收您期望的所有内容。

        此外,read()不会返回以null结尾的字符串,但您对printf()的使用需要一个。检查valread是否有错误,仅当read()成功时才将valread传递给printf()作为输入参数,以便它知道{{1}中实际有多少数据}:

        buffer

        printf("message from client : %.*s\n", valread, buffer);