简体   繁体   中英

C server socket refusing the connection of a python client

I am trying to make a messenger program (that currently has a ton of bugs so please dismiss them) and for some reason, the server wont let the clients connect. I have tried changing the port, but nothing works. I get the following error (for my client, which is in python) (this is on a mac, but I have tried the client on a windows computer, still nothing):

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

Here is the code for the server (written in 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;
}

and the client (written in 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()

regarding the function:

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

and

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

The expression: sizeof(msg) will return a value (depending on your underlying hardware and certain compiler parameters) of 4 or 8, Not what you want. Suggest passing the actual number of bytes to transmit.

regarding the function:

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

and the statement:

return; 

The return; statement is completely unnecessary. Suggest removing that statement.

regarding:

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

This statement can fail. Always check (if socket < 0) then handle the error

regarding:

server.sin_addr.s_addr = INADDR_ANY;

INADDR_ANY has the value: "0.0.0.0" which cannot be directly assigned. Suggest:

server.sin_addr.s_addr = htonl(INADDR_ANY);

OT: regarding:

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

and

listen(s, MAXCLIENTS); 

These functions can fail. Always check the returned value to assure the operation was successful.

OT: regarding:

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

and similar statements. In C, the returned type is void* which can be assigned to any pointer. Casting just clutters the code and is error prone. even this statement has an error in the cast. Suggest removing that cast.

regarding:

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

This code sequence forces serial handling of the incoming sockets. Much better to generate a 'thread pool', then use accept() and pass the resulting client socket to an idle thread. The thread then performs all the communication with the client, then, when finishing with the client, closes the client socket.

regarding:

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

There must already be an open socket to the client, which there is none, so no communication occurs.

there may be other problems, but this should aim you in the right direction.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM