C серверный сокет, отказывающийся от подключения python клиента - PullRequest
0 голосов
/ 07 апреля 2020

Я пытаюсь создать программу обмена сообщениями (которая в настоящее время содержит массу ошибок, поэтому, пожалуйста, отклоните их), и по какой-то причине сервер не позволяет клиентам подключаться. Я попытался изменить порт, но ничего не работает. Я получаю следующую ошибку (для моего клиента, который находится в python) (это на компьютере ma c, но я пробовал клиент на компьютере windows, все еще ничего):

Traceback (most recent call last):
  File "msgclient.py", line 31, in <module>
    Program()
  File "msgclient.py", line 8, in __init__
    self.s.connect((IP, PORT))
ConnectionRefusedError: [Errno 61] Connection refused

Вот код для сервера (записан в c):

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <netinet/in.h>
#include <unistd.h>
#include <sys/types.h>

#define MAXCLIENTS 256
#define MAXMSG 269
#define PORT 9989

void forward(int clientslist[MAXCLIENTS], char* msg) {
    int x;
    for (x=0; x < MAXCLIENTS;  x++){
        send(clientslist[x], msg, sizeof(msg), 0);
    }
    return;
}

int main(){
    int s = socket(AF_INET, SOCK_STREAM, 0);
    int clients[MAXCLIENTS];
    int clientcounter = 0;

    fd_set socketlist, readlist;
    FD_ZERO(&socketlist);
    FD_SET(s, &socketlist);

    struct sockaddr_in server;
    server.sin_family = AF_INET;
    server.sin_port = htons(PORT);
    server.sin_addr.s_addr = INADDR_ANY;

    bind(s, (struct sockaddr*) &server, sizeof(server));
    listen(s, MAXCLIENTS);
    int clientsocket;
    int i;
    int rc;
    int max = s;
    void* msg = (char *) malloc(MAXMSG+1);
    void* usr = (char *) malloc(14);

    while (1){
        readlist = socketlist;
        select(FD_SETSIZE, &readlist, NULL, NULL, NULL);
        for (i=0; i<max+1; i++){
            if(FD_ISSET(i, &readlist)){
                if (i == s){
                    clientsocket = accept(s, NULL, NULL);
                    FD_SET(clientsocket, &socketlist);
                    clients[clientcounter] = clientsocket;
                    clientcounter++;
                    rc = recv(clientsocket, usr, 10, 0);
                    printf("Connection received from %s\n", usr);
                    usr = "\0";
                    if (clientsocket > max+1){
                        max = clientsocket;
                    }
                } else {
                    rc = recv(i, msg, MAXMSG, 0);
                    if (rc > 0){
                        forward(clients, msg);
                    } else{
                        close(i);
                    msg = "\0";
                    }
                }
            }

        }
    }
    return 0;
}

и клиента (написан в python):

import socket

class Program:
    def __init__(self):
        IP = socket.gethostbyname(socket.gethostname())
        PORT = 9989
        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.s.connect((IP, PORT))
        self.user = self.username()
        self.s.send(bytes(self.user, "utf-8"))
        while True:
            received = self.s.recv(269)
            received = received.decode("utf-8")
            print(received)
            self.enter()


    def username(self):
        name = str(input("Enter a username (10 character max): "))
        if len(name) > 10:
            print("Username is larger than 10; try again")
            self.username()
        return name;

    def enter(self):
        msg = str(input("Enter a message>> "))
        if msg != "":
            self.s.send(bytes(f"{self.user}>> {msg}", "utf-8"))

if __name__ == "__main__":
    Program()

1 Ответ

1 голос
/ 08 апреля 2020

относительно функции:

void forward(int clientslist[MAXCLIENTS], char* msg)

и

send(clientslist[x], msg, sizeof(msg), 0);

Выражение: sizeof(msg) вернет значение (в зависимости от используемого оборудования и определенных параметров компилятора) 4 или 8 Не то, что вы хотите. Предложите передать фактическое количество байтов для передачи.

относительно функции:

void forward(int clientslist[MAXCLIENTS], char* msg)

и оператора:

return; 

Оператор return; совершенно не нужен , Предложите удалить это утверждение.

относительно:

int s = socket(AF_INET, SOCK_STREAM, 0); 

Это утверждение может завершиться ошибкой. Всегда проверяйте (если сокет <0), затем обрабатывайте ошибку </p>

, касающуюся:

server.sin_addr.s_addr = INADDR_ANY;

INADDR_ANY имеет значение: "0.0.0.0", которое не может быть назначено напрямую. Предложите:

server.sin_addr.s_addr = htonl(INADDR_ANY);

OT: относительно:

bind(s, (struct sockaddr*) &server, sizeof(server));

и

listen(s, MAXCLIENTS); 

Эти функции могут не работать. Всегда проверяйте возвращаемое значение, чтобы убедиться, что операция прошла успешно.

OT: относительно:

void* msg = (char *) malloc(MAXMSG+1);

и аналогичных операторов. В C возвращается тип void*, который может быть назначен любому указателю. Приведение просто загромождает код и подвержено ошибкам. даже это утверждение имеет ошибку в приведении. Предложите удалить это приведение.

относительно:

readlist = socketlist; 
select(FD_SETSIZE, &readlist, NULL, NULL, NULL); 
for (i=0; i<max+1; i++) 
{ 
    if(FD_ISSET(i, &readlist))
    { 
        if (i == s)
        { 

Эта кодовая последовательность вызывает последовательную обработку входящих сокетов. Намного лучше создать «пул потоков», затем использовать accept () и передать полученный клиентский сокет свободному потоку. Затем поток выполняет всю связь с клиентом, а затем, по окончании работы с клиентом, закрывает сокет клиента.

относительно:

select(FD_SETSIZE, &readlist, NULL, NULL, NULL);

У клиента уже должен быть открытый сокет, которого нет, поэтому связь отсутствует.

могут быть другие проблемы, но это должно направить вас в правильном направлении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...