2014-12-08 3 views
4

저는 여가 시간에 파이썬 게임을하고 있었고 문제가 생겼습니다. 나는 기본 스레드 모듈을 사용하여 소켓 작업을하고 있는데, 클라이언트 하나와 서버 파일에 연결할 때 잘 동작한다. 하지만 그 이상, 그리고 첫 번째 클라이언트와 연결된 첫 번째 클라이언트가 연결된 후에 연결되는 모든 것.스레드를 사용할 때 소켓 문제가 발생했습니다.

여기 서버

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 

나는 연구의 조금 한의 코드이며, 나는 스레딩 모듈에서 잠금을 사용할 필요가 나의 추측은, 그러나 나는 확실하지 않다. 어떤 제안?

미리 감사드립니다.

+0

답을 모르겠지만'thread' 대신에'threading' 모듈을 사용해야합니다. 이것은 상위 인터페이스입니다. – cdonts

+0

질문에 답하기 위해 s.listen (5)은 설정에서 두 번 이상 호출되어서는 안되며 while 루프 밖으로 이동하십시오. 모든 클라이언트에 대해 s.accept() 만 호출해야합니다. – crazyhatfish

+0

'conn.recv'는 부분 메시지를 읽을 수 있으며 코드가 손상됩니다. – Daniel

답변

0

콘솔 입력이 문제 였으므로 아무 것도 없습니다. 심각한 해킹 없이는이 한계를 극복 할 수있는 방법이 없었기 때문에 즉흥적으로 제안했습니다. 내 솔루션은 콘솔을 사용하는 대신 python으로 웹 응용 프로그램을 만드는 것이 었습니다. 이것에 약간 이점이 있었다. 모든 액세스 할 수

  • 서버는 입력이
  • 어떤 파일이 사용자에 대해 다운로드 할 필요가 없다 (내 문제에 대한 해결책)를 입력하는 동안 쉽게
  • 일이 일어날 수 한 번에 여러 개의 입력을 처리 할 수 ​​있습니다 웹 주소를 입력하면됩니다.

완벽한 솔루션은 아니지만 때로는 대안을 찾는 것이 차선책입니다.

대단히 감사합니다!

관련 문제