如何创建非本地服务器Python?

发布于 2025-02-13 02:36:22 字数 4049 浏览 1 评论 0 原文

我有一台非常基本的服务器,用于我的Pygame游戏,但是我不知道是否可以使从不同网络连接的客户端访问服务器。目前,我可以从同一网络连接,但是由于我正在为套接字使用本地IP地址,因此这肯定无法从不同的网络连接。 这是我的四个脚本(其中两个只是类):

文件 server.py

from _thread import *
import pickle
from player import Player

class Server:
    def __init__(self):
        self.players = [Player(0,0,20,20, (255,0,0)), Player(100,100,20,20,(0,0,255))]
        self.numPlayers = 0

        ip = (socket.gethostbyname(socket.gethostname()))
        print (ip)
        port = 5555

        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        try:
            self.s.bind((ip, port))
        except socket.error as e:
            print(e)

    def client_thread(self, conn, player):
        conn.send(pickle.dumps(self.players[player]))
        while True:
            try:
                data = pickle.loads(conn.recv(2048))

                if isinstance(data, Player):
                    self.players[player] = data

                playersToSend = []
                for each in range (0,len(self.players)):
                    if each != player:
                        playersToSend.append(self.players[each])

                conn.send(pickle.dumps(playersToSend))

                if data == "quit":
                    break

                if not data:
                    print ("Disconnected")
                    break
            except EOFError as e:
                break
        print ("Lost Connection")
        self.numPlayers -= 1


serv = Server()

serv.s.listen(20)
print("Waiting for connection, server started")

while True:
    conn, addr = serv.s.accept()
    print (f"Connection found from {addr}")
    start_new_thread(serv.client_thread, (conn,serv.numPlayers))
    serv.numPlayers += 1

file client.py


import pygame
from pygame import QUIT

from Network import Network

pygame.init()
win = pygame.display.set_mode((500,500))
n = Network() # initiate the network object
playerPos = (n.p.x, n.p.y) # connect to the server and get the starting position

print (playerPos[0],playerPos[1])

FPS = pygame.time.Clock()

def move():
    keys = pygame.key.get_pressed()
    if keys[pygame.K_UP]: n.p.y -= n.p.velocity
    if keys[pygame.K_DOWN]: n.p.y += n.p.velocity
    if keys[pygame.K_RIGHT]: n.p.x += n.p.velocity
    if keys[pygame.K_LEFT]: n.p.x -= n.p.velocity
    n.p.update()

while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            n.send("quit")
            pygame.quit()
            exit(0)

    
    move()

    players = [] # reset/set the list
    players = n.send(n.p) #send off the player to the server, to receiver the other player
    
    win.fill((255,255,255))

    for each in players:
        pygame.draw.rect(win, (255,0,0), pygame.Rect(each.rect))
    pygame.draw.rect(win, (0,0,255), pygame.Rect(n.p.rect))

    
    pygame.display.update()
    FPS.tick(60)

file network.py.py

import pickle


class Network:
    def __init__(self):
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.ip = socket.gethostbyname(socket.gethostname())
        self.port = 5555
        self.addr = (self.ip, self.port)
        self.p = self.connect()

    def connect(self):
        self.sock.connect(self.addr)
        p = pickle.loads(self.sock.recv(2048))
        return p

    def send(self, data):
        self.sock.sendall(pickle.dumps(data))
        return pickle.loads(self.sock.recv(2048))

file > player.py

import pickle


class Player():
    def __init__(self, x, y, width, height, colour):
        self.x, self.y = x, y
        self.width, self.height = width, height
        self.colour = colour
        self.velocity = 3

        self.rect = (x, y, width, height)

    def update(self):
        self.rect = (self.x, self.y, self.width, self.height)

    def draw(self, win):
        pygame.draw.rect(win, self.colour, self.rect)

I have a very basic server for my Pygame game going, but I don't know if/how I can make the server accessible from clients connecting from different networks. Currently I can connect from the same network, but because I'm using my local IP address for the socket, surely this won't work for connecting from different networks.
Here are my four scripts (two of which are just classes):

File server.py

from _thread import *
import pickle
from player import Player

class Server:
    def __init__(self):
        self.players = [Player(0,0,20,20, (255,0,0)), Player(100,100,20,20,(0,0,255))]
        self.numPlayers = 0

        ip = (socket.gethostbyname(socket.gethostname()))
        print (ip)
        port = 5555

        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        try:
            self.s.bind((ip, port))
        except socket.error as e:
            print(e)

    def client_thread(self, conn, player):
        conn.send(pickle.dumps(self.players[player]))
        while True:
            try:
                data = pickle.loads(conn.recv(2048))

                if isinstance(data, Player):
                    self.players[player] = data

                playersToSend = []
                for each in range (0,len(self.players)):
                    if each != player:
                        playersToSend.append(self.players[each])

                conn.send(pickle.dumps(playersToSend))

                if data == "quit":
                    break

                if not data:
                    print ("Disconnected")
                    break
            except EOFError as e:
                break
        print ("Lost Connection")
        self.numPlayers -= 1


serv = Server()

serv.s.listen(20)
print("Waiting for connection, server started")

while True:
    conn, addr = serv.s.accept()
    print (f"Connection found from {addr}")
    start_new_thread(serv.client_thread, (conn,serv.numPlayers))
    serv.numPlayers += 1

File client.py


import pygame
from pygame import QUIT

from Network import Network

pygame.init()
win = pygame.display.set_mode((500,500))
n = Network() # initiate the network object
playerPos = (n.p.x, n.p.y) # connect to the server and get the starting position

print (playerPos[0],playerPos[1])

FPS = pygame.time.Clock()

def move():
    keys = pygame.key.get_pressed()
    if keys[pygame.K_UP]: n.p.y -= n.p.velocity
    if keys[pygame.K_DOWN]: n.p.y += n.p.velocity
    if keys[pygame.K_RIGHT]: n.p.x += n.p.velocity
    if keys[pygame.K_LEFT]: n.p.x -= n.p.velocity
    n.p.update()

while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            n.send("quit")
            pygame.quit()
            exit(0)

    
    move()

    players = [] # reset/set the list
    players = n.send(n.p) #send off the player to the server, to receiver the other player
    
    win.fill((255,255,255))

    for each in players:
        pygame.draw.rect(win, (255,0,0), pygame.Rect(each.rect))
    pygame.draw.rect(win, (0,0,255), pygame.Rect(n.p.rect))

    
    pygame.display.update()
    FPS.tick(60)

File network.py

import pickle


class Network:
    def __init__(self):
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.ip = socket.gethostbyname(socket.gethostname())
        self.port = 5555
        self.addr = (self.ip, self.port)
        self.p = self.connect()

    def connect(self):
        self.sock.connect(self.addr)
        p = pickle.loads(self.sock.recv(2048))
        return p

    def send(self, data):
        self.sock.sendall(pickle.dumps(data))
        return pickle.loads(self.sock.recv(2048))

File player.py

import pickle


class Player():
    def __init__(self, x, y, width, height, colour):
        self.x, self.y = x, y
        self.width, self.height = width, height
        self.colour = colour
        self.velocity = 3

        self.rect = (x, y, width, height)

    def update(self):
        self.rect = (self.x, self.y, self.width, self.height)

    def draw(self, win):
        pygame.draw.rect(win, self.colour, self.rect)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

抚你发端 2025-02-20 02:36:22

要从其他网络连接到您的服务器,您需要设置Internet路由器以将请求从Internet转发到计算机。这将通过在路由器的IP地址打开配置页面(只需打开 http://< your_routers_ip> 在浏览器中)。
不过,除非您的计算机一直在线,否则最好使用 pythonanywhere 它是Python WebApps的托管服务。

To connect to your server from other networks, you would need to set up your internet router to forward requests from the internet to your machine. This would be done by opening the configuration page on the router's ip address (just open http://<your_routers_ip> in a browser).
Unless your computer is online all the time, though, it would be better to use something like pythonanywhere to host your game, as it is a hosting service for python webapps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文