我将服务器类定义如下(已编辑):
class server:
def __init__( self, ip = "", port = 0 ):
self.SetAddress( ip, port )
self.__players = []
def __SetSocket( self, blocking = 0, queue = 4 ):
self.__listener = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
self.__listener.bind( self.GetAddress() )
self.__listener.setblocking( blocking )
self.__listener.setsockopt( socket.SOL_SOCKET, socket.SO_REUSEADDR, 1 )
self.__listener.listen( queue )
self.__listener.settimeout( 5 )
self.__read, self.__write, self.__error = [ self.__listener ], [], []
def __AddClient( self, source ):
c, a = source.accept()
c.settimeout( 5 )
self.__read.append( c )
send( c, "Welcome!" )
print a, "Connection established"
return
def __AddPlayer( self, source, nick ):
if len( self.__players ) == 4:
send( source, ('Error', "4 players already connected.") )
self.__read.remove( source )
return
self.__players.append( nick )
send( source, ('ID', self.__players.index(nick)) )
def __RemovePlayer( self, source, gamer_id ):
self.__players.pop( gamer_id )
self.__read.remove( source )
source.close()
def __Connect( self ):
joining = True
while joining:
r, w, x = select( self.__read, self.__write, self.__error, 0 )
for s in r:
if s is self.__listener:
self.__AddClient( s )
else:
data = receive( s )
if data:
print data, s.getpeername()
if self.__MaintainPlayers( s, data ):
pass
if len( self.__players ) == 4:
joining = False
return
def __MaintainPlayers( self, source, data ):
if data[0] == "Nick":
self.__AddPlayer( source, data[1] )
return True
elif data[0] == "Quit":
self.__RemovePlayer( source, data[1] )
return True
return False
def run( self ):
self.__SetSocket( 1, 4 )
print "Waiting for players."
self.__Connect()
Run Code Online (Sandbox Code Playgroud)
其中,发送和接收函数如下:
def send( channel, message ):
try:
channel.send( json.dumps(message) )
return True
except OSError as e:
print e
return False
def receive( channel, packet_size = 64 ):
try:
data = channel.recv( int(packet_size) )
if not data:
return None
print data
return json.loads( data.strip() )
except OSError as e:
print e
return False
Run Code Online (Sandbox Code Playgroud)
该client课程非常简单(已编辑):
class client:
def __init__( self, name, srvIP, srvPort ):
ip = socket.gethostbyname( socket.gethostname() )
self.__server_address = self.__server_ip, self.__server_port = srvIP, srvPort
self.__ID = None
self.__nick = name
self.__SetListener()
def __SetListener( self ):
self.__listener = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
self.__listener.settimeout( 5 )
try:
self.__listener.connect( self.__server_address )
except Exception, e:
print "Unable to connect", e
raise e
print "Connected to %s:%d." % self.__server_address
send( self.__listener, ("Nick", self.__nick) )
def run( self ):
self.__read, self.__write, self.__error = [ self.__listener ], [], []
while True:
r, w, x = select( self.__read, self.__write, self.__error, 0 )
for f in r:
if f is self.__listener:
data = receive( f )
if data:
print data
if data[0] == "ID":
self.__ID = int( data[1] )
# More conditions
Run Code Online (Sandbox Code Playgroud)
什么情况是,我的客户对象receive的Welcome与ID消息同时进行。这将引发如下异常:
$ client.py
Connected to 10.109.1.92:7777.
"Welcome!"["ID", 0]
Traceback (most recent call last):
File "%PATH%\client.py", line 115, in <module>
c.run()
File "%PATH%\client.py", line 86, in run
data = receive( f )
File "%PATH%\connect.py", line 17, in receive
return loads( data.strip() )
File "%PYTHON%\lib\json\__init__.py", line 338, in loads
return _default_decoder.decode(s)
File "%PYTHON%\lib\json\decoder.py", line 369, in decode
raise ValueError(errmsg("Extra data", s, end, len(s)))
ValueError: Extra data: line 1 column 28 - line 1 column 37 (char 27 - 36)
Run Code Online (Sandbox Code Playgroud)
也就是说,客户端将以下内容作为单个字符串接收:
Run Code Online (Sandbox Code Playgroud)"Welcome!"["ID", 0]
这在json.loads.
是否有某种方法可以在消息之间引入任何类型的延迟?
或者,如果您可以保证您的消息不包含特定字符(例如空字节),您可以将其附加到您的字符串中,然后在服务器端,将字符串拆分为空字符:
客户:
socket.sendall(json_string + '\0')
Run Code Online (Sandbox Code Playgroud)
服务器:
recv_buffer = ""
while True:
data = connection.recv(128)
recv_buffer = recv_buffer + data
strings = recv_buffer.split('\0')
for s in strings[:-1]:
print("Received: %s" % s)
recv_buffer = strings[-1]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4606 次 |
| 最近记录: |