Python中的Socket服务器

0 投票
1 回答
2777 浏览
提问于 2025-04-17 13:50

我正在尝试搭建一个本地服务器,这样同一局域网内的其他电脑就可以连接到它。当我在客户端尝试连接时,出现了以下错误信息:
[Errno 10061] 无法连接,因为目标机器主动拒绝了连接。

我已经搜索了几个小时,但仍然无法解决这个问题。我还尝试关闭了防火墙,但还是没有用。

这是我的服务器和客户端代码:

服务器代码:

import socket
import threading
import SocketServer
import datetime

ver_codes = []



class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):
    def handle(self):
        print threading.current_thread().isDaemon()
        data = self.request.recv(1024)
        command = data.split()[0]
        if(command=="login"):
            if(logged_in(data.split()[1])==False):
                self.request.sendall(login(data.split()[1], data.split()[2]))
            else:
                self.request.sendall("already in")


class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
    pass

def client(ip, port, message):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((ip, port))
    try:
        sock.sendall(message)
        response = sock.recv(1024)
        print "Received: {}".format(response)
    finally:
        sock.close()

def logged_in(id_num):
    for i in ver_codes:
        if(i[0]==id_num):
            return True
    return False

def login(username, password):
    login_file = open("Login.txt", "r")
    match = login_file.readline()
    while(match!="*"):
        if(match.split()[0]==username):
            if(match.split()[1]==password):
                ver_codes.append([match.split()[0], encryption_code(match.split()[2])])
                login_file.close()
                return "{} {}".format(match.split()[2], encryption_code(match.split()[2]))
                print "And Here"
        match = login_file.readline()
    return "Denied"
    login_file.close()

def encryption_code(to_encrypt):
    now = datetime.datetime.now()
    return int(str(now.microsecond)) * int(to_encrypt)


if __name__ == "__main__":
HOST, PORT = "localhost", 7274

server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler)
ip, port = server.server_address
print server.server_address

server_thread = threading.Thread(target=server.serve_forever)
server_thread.daemon = False
server_thread.start()
print "Server loop running in thread:", server_thread.name

客户端代码:

import socket
import sys

HOST, PORT = "localhost", 7274
data = " ".join(sys.argv[1:])

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

try:
sock.connect((HOST, PORT))
sock.sendall("login mahdiNolan m1373")

received = sock.recv(1024)
finally:
sock.close()

非常感谢你们能提供的任何帮助!提前谢谢大家!

1 个回答

1

你的问题是因为你在监听 localhost,这只会接受来自本机的连接。

如果你想接受来自任何地方的连接,别用 "localhost",直接用空字符串 ""。这就相当于在C语言的套接字API中指定 INADDR_ANY。想了解更多,可以查看这个链接,或者这个页面也有一些有用的解释。简单来说,这意味着“接受来自任何本地接口的连接”。

如果不想用空字符串,你也可以指定一个本地接口的IP地址,这样就只会在那个接口上接受连接。一般来说,除非你的机器里有多个网卡(比如作为网关使用),否则你不太需要这样做,因为你可能只想在某个网络上处理请求。

另外,在客户端那边,你应该使用实际的机器地址——把 "localhost" 替换成服务器机器的IP地址或主机名。例如,可以用 "192.168.0.99"。如果你想在Windows下找到服务器的IP地址,可以打开一个DOS窗口,运行 ipconfig 命令,找那一行写着 IPv4 Address 的信息(假设你有IPv4网络,这种情况很常见)。

Windows防火墙也会阻止服务器接受连接,正如你已经发现的那样,但你不需要关闭它——当你运行服务器时,应该会弹出一个窗口,你可以在里面设置允许接受连接(这是在Windows 7上的情况,其他版本可能会有所不同)。总之,关闭软件防火墙应该能让一切正常工作,不过这是否会带来安全风险就不在这个问题的讨论范围内了。

撰写回答