C服务器套接字拒绝python客户端的连接

时间:2020-04-07 14:08:45

标签: python c sockets networking

我正在尝试制作一个Messenger程序(当前有大量错误,因此请消除它们),由于某种原因,服务器不会让客户端连接。我尝试过更改端口,但是没有任何效果。我收到以下错误(对于我的客户端,这是在python中)(这是在Mac上,但是我已经在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 个答案:

答案 0 :(得分:1)

有关功能:

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)然后处理错误

关于:

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);

客户端必须已经有一个开放的套接字,没有套接字,因此不会发生通信。

可能还有其他问题,但这应该将您对准正确的方向。