使用线程时的套接字问题 [英] Socket issue when using threads

查看:72
本文介绍了使用线程时的套接字问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在业余时间一直在开发python游戏,但遇到了问题.我正在使用基本线程模块处理套接字,当我使用一个客户端连接到服务器文件时,它可以正常工作.但是,不仅如此,在第一个之后连接的任何服务器都会冻结服务器和第一个客户端.

I've been working on a python game in my spare time, and I've run into a problem. I'm working with sockets using the basic threads module, and it works fine when I connect to the server file with one client. But more than that, and any that connect after the first freezes up the server and the first client.

这是服务器的代码

import socket
import random
import thread
from saveState import Save
from grid import Grid   
import time
players = 0
save = Save()
grid = Grid()

def ready(c):
    ready = raw_input("Are you ready to play?\n")
    if(ready == "yes" or ready == "y"):
        grid.makeGrid() 
        c.send("ready")
def clientThread(conn,players):

    while True:
        print "taking requests"
        request = conn.recv(1024)
        segments = request.split(",,")
        if(segments[0] == "0" and players<200):
            print "registering player", addr
            serial = random.choice(list(range(999999)))
            conn.send("{}".format(serial))
            save.players[serial] = segments[2:]
            print save.players[serial][9]
            players+=1
        elif(segments[0] == "3"):
            if(segments[2] == "land"):
                conn.send("{},,{},,{},,{}".format(grid.getLandType(int(save.players[serial][9]),int(save.players[serial][10])), grid.getDesc(int(save.players[serial][9]),int(save.players[serial][10])),int(save.players[serial][9]),int(save.players[serial][10])))
        elif(segments[0]=="2"):
            if(segments[2]=="playerX" and int(segments[3])==-1):
                save.players[serial][9] = int(save.players[int(serial)][9])-1 
            elif(segments[2]=="playerX"):
                save.players[serial][9] = int(save.players[int(serial)][9])+1 
            if(segments[2]=="playerY" and int(segments[3])==-1):
                save.players[serial][10] = int(save.players[int(serial)][10])-1 
            elif(segments[2]=="playerY"):
                save.players[serial][10] = int(save.players[int(serial)][10])+1 
        elif(segments[0]=="4"):
            alreadySent = []
            for m in grid.monsters:
                if(m.X==save.players[int[segment[1]]][9] and m.Y==save.players[int[segment[1]]][10] and alreadySent[m]==False):
                    conn.send("{},,{}".format(m.name, True))
                elif(time.clock == 60*60*(12+8)):
                    conn.send("{},,{}".format("You see the sun set on the horizon. Monsters will be more aggressive now.", False))
        else:       
            print "sorry, there is an inconsistency in the request or the queue is full."



try:
    #start up socket
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    name = socket.gethostbyname(socket.gethostname())
    print name
    port = input("select port\n")
    s.bind((name, port))
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    #listen for any attempts to connect to the api
    #if anyone connects, give them a serial number and add their data to a storage file
    while True: 
        s.listen(5)
        c,addr = s.accept()
        thread.start_new_thread(ready,(c,))
        thread.start_new_thread(clientThread,(c, players))
    conn.close
    sock.close
except socket.error:
    print " either the server port is closed or in use. try again"

和客户

import random
from grid import Grid
from player import Player
from descriptions import Descriptions
import socket
import time
import thread
description = Descriptions()

def descisionHandler(s,serial):
    while True:
        s.send("{},,{},,{}".format(3,serial,"land"))
        response = s.recv(1024).split(",,")
        print "you are on a {} tile \n {} \n {} \n {}".format(response[0], response[1],response[2], response[3])
        action=raw_input("What Will You Do?\n")
        try:
            if(action == "west" and player.locX>0):
                s.send("{},,{},,{},,{}".format(2,serial,"playerX",-1))
                time.sleep(0.5)
            elif(action == "east" and player.locX<199):
                s.send("{},,{},,{},,{}".format(2,serial,"playerX",1))
                time.sleep(0.5)
            elif(action == "north" and player.locY>0):
                s.send("{},,{},,{},,{}".format(2,serial,"playerY",-1))
                time.sleep(0.5)
            elif(action == "south" and player.locY<199):
                s.send("{},,{},,{},,{}".format(2,serial,"playerY",1))
                time.sleep(0.5)
          #  elif(action == "attack" and monster_data[1]):
              #  print "The {} wakes up! A battle begins!".format(monster_data[0])
            elif(action == "profile"):
                print " You are {} \n  {} \n your role is {} \n you have an attack of {} \n a defense of {} \n a speed of {} \n and {} hitpoints \n attacks: {} \n you are located at  {} {}".format(player.name,
                    player.backstory,player.role,player.attack,player.defense,player.speed, player.hitpoints, player.attacks, player.locX, player.locY)
            elif(action == "exit"):
                break
        except IndexError:
            pass

def eventHandler(s,serial):
    while True:
        s.send("{},,{}".format(4,serial))
        response = s.recv(1024).split(",,")
        print response[0]
        return bool(response[1])



while True:
    try:
        print "\nWelcome to Overseer! We need a few things before we begin\n"
        name = raw_input("What is your name?\n")
        backstory = raw_input("What is in your past: choose one \n chosen \n magician \n poet\n")
        role = raw_input("what is your class: choose one \n Warrior \n Mage \n Rougue \n Bard\n")
        player = Player(name,description.player_backstory[backstory], role, 5,5,5,10, {"scrap": 10}, random.choice(list(range(200))), random.choice(list(range(200))))

        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        host = raw_input("what host are you connecting to?")
        port = input("what port?\n")

        s.connect((host,port))
        print "connection successful." 
        time.sleep(5)
        s.send("{},,{},,{},,{},,{},,{},,{},,{},,{},,{},,{},,{},,{}".format(0,0,name,backstory,role,5,5,5,5,10,player.attacks,player.locX,player.locY))
        serial = s.recv(1024)
        print "You're serial number is {}".format(serial)
        while(s.recv(1024) != "ready"):
            pass
        break
    except socket.error:
        print "server is not running or is busy. please try again."

eventThread = thread.start_new_thread(eventHandler,(s,serial))
descisionThread = thread.start_new_thread(descisionHandler,(s,serial))

while 1:
    pass

我做了一些研究,我最好的猜测是我需要使用线程模块中的锁,但是我不确定.有什么建议吗?

I did a bit of research and my best guess is that I need to use locks from the threading module, but I'm not sure. any suggestions?

提前谢谢!

推荐答案

所以问题出在控制台输入上,正如TheSmallNothing所说的那样.没有严重的黑客攻击,实际上没有办法解决此限制,所以我提议即兴创作.我的解决方案是使用python创建一个Web应用程序,而不是使用控制台.这样做有一些好处.

So the issue was the console input, as theSmallNothing said. There wasn't really a way around this limitation without serious hacking, so I proposed to improvise. My solution was to create a web app with python instead of using a console. There were a few advantages to this.

  • 服务器可以一次轻松处理多个输入
  • 输入输入时可能会发生(我的问题的解决方案)
  • 无需为用户下载文件,因为只需输入网址即可访问所有内容.

虽然不是完美的解决方案,但有时找到替代方法却是下一个最好的选择.

While not a perfect solution, sometimes finding an alternative is the next best thing.

谢谢大家的帮助!

这篇关于使用线程时的套接字问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆