2017-02-15 83 views
0

所以我想做的是做一個多線程服務器,爲每個連接到它的客戶端創建線程,並回應從客戶端發送的字符串。如何結束服務器套接字監聽

它有點作品,但我的服務器實際上並沒有正常結束。我的KerboardInterrupt catch在windows命令提示符下似乎不起作用,只有讓我退出進程的東西是ctrl + pause/break。任何人都可以幫助我想辦法讓服務器優雅地結束嗎?

服務器代碼:

import socket 
import threading 
import time 
import datetime 
import sys 

def getTime(): 
    ts = time.time() 
    timeStamp = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-  %d_%H:%M:%S') 
    return timeStamp 

def ThreadFunction(clientsocket, clientaddr): 
    global ReceivedData 
    global SentData 
    while True: 

     #Receive data from client 
     data = clientsocket.recv(bufferSize) 
     #Get client IP and port 
     clientIP, clientSocket = clientsocket.getpeername() 

     #Add to total amount of data transfered 
     ReceiveDataSize = len(data) 
     ReceivedData += ReceiveDataSize 

     #LOg the received data 
     text_file.write(str(getTime()) + "__ Size of data received (" +  clientIP + ":" + str(clientSocket) + ") = " + str(ReceiveDataSize) + '\n') 

     #Send data 
     clientsocket.send(data) 
     SentDataSize = len(data) 
     SentData += SentDataSize 

     #Log the sent data 
     text_file.write(str(getTime()) + "__ Size of data sent (" + clientIP + ":" + str(clientSocket) + ") = " + str(SentDataSize) + '\n') 


def Close(counter, ReceivedData, SentData): 
    print ("Shutting down Server...") 
    serversocket.close() 
    text_file.write("\n\nTotal # of connections: " + str(counter)) 
    text_file.write("\nTotal data received: " + str(ReceivedData)) 
    text_file.write("\nTotal data sent: " + str(SentData)) 
    text_file.close() 
    sys.exit() 


if __name__ == '__main__': 

    serverIP = raw_input('Enter your server IP \n') 
    port = int(raw_input('What port would you like to use?\n')) 

    # Maintain how many connections 
    connections = [] 
    counter = 0 

    # Maintain amount of data sent to and from server 
    ReceivedData = 0 
    SentData = 0 
    bufferSize = 1024 

    # Create and initialize the text file with the date in the filename in the logfiles directory 
    text_file = open("MultiThreadedServerLog.txt", "w") 
    address = (serverIP, port) 
    serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

    # Bind server to port 
    serversocket.bind(address) 

    # The listen backlog queue size 
    serversocket.listen(50) 
    print ("Server is listening for connections\n") 

    try: 
     while 1: 
      # Accept client connections, increment number of connections 
      clientsocket, clientaddr = serversocket.accept() 
      counter += 1 

      # Log client information 
      print (str(clientaddr) + " : " + " Just Connected. \n Currently connected clients: " + str(counter) + "\n") 
      text_file.write(str(getTime()) + " - " + str(clientaddr) + " : " + " Just Connected. \n Currently connected clients: " + str(counter) + "\n") 
      clientThread = threading.Thread(target=ThreadFunction, args=(clientsocket, clientaddr)) 
      clientThread.start() 

    except KeyboardInterrupt: 
     print ("Keyboard interrupt occurred.") 
     Close(counter, ReceivedData, SentData) 

客戶端代碼:

from socket import * 
import threading 
import time 
import random 
import sys 
import datetime 


serverIP = "" 
port = 8005 
message = "" 
msgMultiple = 1 


def getTime(): 
    ts = time.time() 
    timeStamp = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d_%H:%M:%S') 
    return timeStamp 



def run(clientNumber): 
    buffer = 1024 

    global totalTime 

    s = socket(AF_INET, SOCK_STREAM) 
    s.connect((serverIP, port)) 
    threadRTT = 0 

    while 1: 
     for _ in range(msgMultiple): 
      cData = message + " From: Client " + str(clientNumber) 

      # Start timer and send data 
      start = time.time() 
      s.send(cData.encode('utf-8')) 
      print "Sent: " + cData 

      # Stop timer when data is received 
      sData = s.recv(buffer) 
      end = time.time() 

      # Keep track of RTT and update total time 
      response_time = end - start 
      threadRTT += end - start 
      totalTime += response_time 
      print "Received: " + cData + '\n' 
      t = random.randint(0, 9) 
      time.sleep(t) 

     # Log information of Client 
     text_file.write(
      "\nClient " + str(clientNumber) + " RTT time taken for " + str(msgMultiple) + " messages was: " + str(
       threadRTT) + " seconds.") 
     threadRTT = 0 
     break 


if __name__ == '__main__': 
    serverIP = raw_input('Enter the server IP: ') 
    port = int(input('Enter the port: ')) 
    clients = int(input('Enter number of clients: ')) 
    message = raw_input('Enter a message to send: ') 
    msgMultiple = int(input('Enter the number of times you would like to send the message: ')) 

    # Initialize Log file 
    text_file = open("ClientLog.txt", "w") 

    # Used to maintain list of all running threads 
    threads = [] 
    totalTime = 0 

    # Create a seperate thread for each client 
    for x in range(clients): 
     thread = threading.Thread(target=run, args=[x]) 
     thread.start() 
     threads.append(thread) 

    for thread in threads: 
     thread.join() 
    # Calculations for log data 
    bytes = sys.getsizeof(message) 
    totalRequests = clients * msgMultiple 
    totalBytes = totalRequests * bytes 
    averageRTT = totalTime/totalRequests 
    # Output data 
    print("Bytes sent in message was : " + str(bytes)) 
    print("Total Data sent was : " + str(totalBytes) + " Bytes.") 
    print("Average RTT was : " + str(averageRTT) + " seconds.") 
    print("Requests was : " + str(totalRequests)) 

    # Write data to log file 
    text_file.write("\n\n Bytes sent in message was : " + str(bytes)) 
    text_file.write("\nTotal Data sent was : " + str(totalBytes) + " Bytes.") 
    text_file.write("\nAverage RTT was : " + str(averageRTT) + " seconds.") 
    text_file.write("\nRequests was : " + str(totalRequests)) 

此外,如果任何人有他們會加入到這個代碼的普遍改善,讓我知道。我對python仍然很陌生,但仍然很粗糙。

這是我從我的服務器得到的正常預期輸入。

enter image description here

但是當它到達連接的最後一個客戶端,它開始拖上某種原因。

enter image description here

的最終圖像,輸入繼續爲廣大的文本文件,很長一段時間。似乎有些事情沒有正確結束。

+0

哪個'EOF'?套接字,數據包,文件對象? – dsgdfg

+0

'KeyboardInterrupt'只會結束主線程。你必須添加一個控制機制來結束子線程。 –

+0

@KlausD。我試圖讓我的線程成爲一個守護進程,但那不起作用。任何其他方式我可以結束線程? –

回答

0

通過添加if語句解決,該語句檢查字節< 0,如果是,則結束套接字。