2015-11-09 57 views
0

我所有的客戶插座做同樣的事情:發送每一秒(22個字節)包如下如何保持通過監聽連接的TCP套接字「選擇」

Server代碼:

import select 
import socket 
import datetime 
SList = [] 


class Tserver: 

    def __init__(self, portNum): 
     host = '127.0.0.1' 
     self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
     self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
     self.server.bind((host, portNum)) 
     self.server.listen(1) 


def GETPACK(): 
    # function for CRC check 
    def CRC(DATA_STR): 
     return 1 

    # generate 100 sockets to listen 
    for x in range(100): 
     SList.append(Tserver(x+10000)) 

    inputs = [] 
    # put in inputs 
    for x in range(100): 
     inputs.append(SList[x].server) 

    while(True): 
     ready_socks, _, _ = select.select(inputs, [], []) 
     for sock in ready_socks: 
      c, addr = sock.accept() 
      while(True): 
       data = c.recv(22) 
       if len(data) == 22: # To make sure the data-length is 22 
        # Turn the pack string into bytearray 
        data_bytes = bytearray() 
        data_bytes.extend(data) 
        if CRC(data_bytes) == 1: 
         print "Connected from client IP Address:" + str(addr) 
         # ID 
         ID = 256*data_bytes[1] + data_bytes[2] 
         print "ID: ", ID 
         now = datetime.datetime.now() 
         print "now: ", str(now) 

if __name__ == "__main__": 
    GETPACK() 

我的服務器只能打印由第一個連接的套接字發送的包。 而我的問題是如何打印出每個端口發送到服務器的所有消息。

+1

您是否嘗試調試您的代碼? – peterh

+0

套接字只是不這樣工作。您應該重新閱讀我相信的套接字文檔。您只創建一個套接字來偵聽端口,然後'accept'將爲每個連接返回一個新創建的套接字。 – spectras

+0

@peterh不是,我仍在努力。需要一些好的建議。 –

回答

1

有關如何使用select模塊編寫基於選擇的服務器的詳細說明,請參閱this PyMOTW entry

這個例子和你的代碼之間的主要區別是:

您只需要創建一個監聽套接字 - server。不需要監聽多個端口。

變量inputs將成爲一個列表,包括server和任何其他客戶端的開放套接字連接。

你的業務循環的樣子:

while true: 
    readable, _, _ = select.select(inputs, [], []) 
    for r in readable: 
    if r is server: 
     # handle a new incoming connection 
     # this will add an entry to the variable inputs 
    else: 
     # read some data from socket r and process it 

當您嘗試從客戶端套接字讀取,並得到一個EOF條件下,可以關閉套接字,並從inputs變量將其刪除。

0

@ErikR感謝您的幫助,我更改了我的代碼,並且它工作正常。

我的代碼不工作是因爲兩件事情的原因是:

1.I只能創建一個連接從我的客戶recv的數據。

2,相同的連接不能用於recv的再次認可,如果客戶端重新連接簡化版,(我的代碼不檢查異常,當客戶端關機)

代碼如下:

import select, socket, datetime 
SList = [] 
SconnList = [] 

class Tserver: 
    def __init__(self, portNum): 
     host = '127.0.0.1' 
     self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
     self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1) 
     self.server.bind((host,portNum)) 
     self.server.listen(1) 
     print "Server ports: "+str(portNum) 

class Sconn: 
    def __init__(self, sock): 
     self.conn, self.addr = sock.accept()   

def GETPACK(): 
    # function for CRC check 
    def CRC(DATA_STR): 
     return 1 

    # generate 100 sockets to listen   
    for x in range(100): 
     SList.append(Tserver(x+10000)) 

    inputs = [] 
    # put in inputs 
    for x in range(100): 
     inputs.append(SList[x].server) 

    while(True): 
     ready_socks,_,_ = select.select(inputs, [], []) 
     for sock in ready_socks: 
      try: 
       SconnList.append(Sconn(sock)) 
       SconnList.reverse() 
       inputs.append(SconnList[0].conn) 
      except:  
       data = sock.recv(22) 
       if len(data) == 22: # To make sure the data-length is 22 
       #Turn the pack string into bytearray 
        data_bytes = bytearray() 
        data_bytes.extend(data) 
        if CRC(data_bytes) == 1: 
         print "IP Address:" + str(sock.getsockname()) 
         #ID 
         ID = 256*data_bytes[1] + data_bytes[2] 
         print "ID: ",ID 
         now = datetime.datetime.now() 
         print "now: ",str(now) 
         print "" 
         print "" 

if __name__ == "__main__": 
    GETPACK()