2017-02-15 7 views
0

私は何をしようとしているのは、接続するクライアントごとにスレッドを作成し、クライアントから送られた文字列を返信するマルチスレッドサーバを作ることです。サーバソケットを終了するにはどうすればいいですか?

それはうまく機能しますが、サーバーは実際に正しく終了しません。私のKerboardInterruptキャッチは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'はメインスレッドのみを終了します。サブスレッドを終了するための制御機構を追加する必要があります。 @KlausD。 –

+0

スレッドをデーモンにしようとしましたが、うまくいきませんでした。他の方法でスレッドを終了できますか? –

答えて

0

バイトが<であるかどうかを調べるifステートメントを追加して解決します。ある場合は、ソケットを終了します。

関連する問題