import sys, os, socket
import pickle
+import signal
from daemon import Daemon
from Util import *
-
-PORT = 10001
-HOST = "127.0.0.1"
-
-BUFFER_SIZE = 1024
+from Util import SERVER_HOST, SERVER_PORT
+from BitTorrentClientRun import *
+from TransmissionRun import *
+from TriblerRun import *
+BUFFER_SIZE = 4096
states = {} # keeps track of what kind of message was previously receveid on a socket.
-
+processes = {}
WAITING_MSG_TYPE = 0
-WAITING_CONFIG_DATA = 2
WAITING_START_DATA = 3
WAITING_STOP_DATA = 4
WAITING_STATUS_DATA = 5
-clients_data = []
-
+DEBUG = True
def recv_pickled_data(clientsock):
-# while chunk:
-# chunk = clientsock.recv(BUFFER_SIZE)
-# data += chunk
- data = clientsock.recv(BUFFER_SIZE)
+ # while chunk:
+ # chunk = clientsock.recv(BUFFER_SIZE)
+ # data += chunk
+ data = clientsock.recv(BUFFER_SIZE)
+ dd = pickle.loads(data)
+ return dd
- dd = pickle.loads(data)
- return dd
+""" Starts a process for a BitTorrent client and returns its pid.
+ @return: -1, if any error is encountered
+"""
def start_bt_client(bt_client_data):
- pass
-
+ btcr = None
+
+ if bt_client_data[CLIENT] == TRANSMISSION:
+ btcr = TransmissionRun(bt_client_data[BASE_DIR])
+ elif bt_client_data[CLIENT] == TRIBLER:
+ btcr = TriblerRun(bt_client_data[BASE_DIR])
+
+ else:
+ return -1
+
+ btcr.config_run(bt_client_data[DL_DIR], bt_client_data[LOG_DIR],
+ bt_client_data[OUT_FILE], bt_client_data[LOG_DIR],
+ bt_client_data[LOG_FILE], bt_client_data[PORT],
+ bt_client_data[TORRENT])
+
+ btcr.start()
+ [pid, log_fd, output_fd] = btcr.run_client(btcr.simple_run_command)
+ processes[pid] = (log_fd, output_fd)
+ print processes[pid]
+ if(DEBUG):
+ print "Server: started client with pid = ", pid
+ return pid
+
+ """Simple test
+
+ btcr = TransmissionRun("/usr/bin/transmissioncli")
+ btcr.config_run("/home/adriana/p2p/p2p-dld/transmission",
+ "/home/adriana/p2p/p2p-log/transmission",
+ "scrubs.out", "/home/adriana/p2p/",
+ "transmission-scrubs.log", 10150,
+ "/home/adriana/p2p/p2p-meta/scrubs.torrent")
+
+ btcr.start()
+ btcr.run_client(btcr.simple_run_command)
+ """
+
+def stop_bt_client(pid):
+
+ int_pid = int(pid)
+ os.kill(int_pid, signal.SIGKILL) # kill generates zombies
+ os.wait()
+ processes[int_pid][0].close()
+ processes[int_pid][1].close()
+ del processes[int_pid]
+ if(DEBUG):
+ print "Server: killed process with pid = ", pid
def doServer():
- #os.spawnvp(os.P_NOWAIT,"/usr/bin/transmission",[])
- serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- serversocket.bind((HOST, PORT));
- serversocket.listen(10) #max 10 requests
-
- while(1):
- (clientsock, address) = serversocket.accept();
- if clientsock not in states:
- states[clientsock] = WAITING_MSG_TYPE;
-
- if states[clientsock] == WAITING_MSG_TYPE:
- print states[clientsock]
- msg = clientsock.recv(BUFFER_SIZE)
-
- msg_types = {
- CONFIG_MSG: WAITING_CONFIG_DATA,
- START_MSG: WAITING_START_DATA,
- STOP_MSG: WAITING_STOP_DATA,
- STATUS_MSG: WAITING_STATUS_DATA
- }
- if msg not in msg_types:
- clientsock.send(ERROR_MSG +"wrong message type " + msg)
- else:
- states[clientsock] = msg_types[msg]
- clientsock.send(ACK_MSG)
- #else:
- print states[clientsock]
- if states[clientsock] == WAITING_CONFIG_DATA:
- clients_data = recv_pickled_data(clientsock)
-
- elif states[clientsock] == WAITING_START_DATA:
- bt_client_data = recv_pickled_data(clientsock)
- start_bt_client(bt_client_data)
-
- elif states[clientsock] == WAITING_STOP_DATA:
- config = recv_pickled_data(clientsock)
-
- elif states[clientsock] == WAITING_STATUS_DATA:
- config = recv_pickled_data(clientsock)
-
- states[clientsock] = WAITING_MSG_TYPE
-
-
- # clientsock.recv(BUFFER_SIZE)
- # recv_pickled_data(clientsock)
- clientsock.send(ACK_MSG)
- clientsock.close()
+ serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ if(DEBUG):
+ print "Server: host ip = %s, port = %d"%(SERVER_HOST,SERVER_PORT)
+ serversocket.bind((SERVER_HOST, SERVER_PORT));
+ serversocket.listen(10) #max 10 requests
+ clientsocks = []
+ while(1):
+ if(DEBUG):
+ print "Server: accepting connections"
+ (clientsock, address) = serversocket.accept();
+ if(DEBUG):
+ print "Server: accepted connection from ", address
+
+ if clientsock not in states:
+ states[clientsock] = WAITING_MSG_TYPE;
+
+ if states[clientsock] == WAITING_MSG_TYPE:
+ print states[clientsock]
+ msg = clientsock.recv(BUFFER_SIZE)
+ if(DEBUG):
+ print "Server: received message:\n", msg
+ msg_types = {
+ START_MSG: WAITING_START_DATA,
+ STOP_MSG: WAITING_STOP_DATA,
+ STATUS_MSG: WAITING_STATUS_DATA
+ }
+ if msg not in msg_types:
+ clientsock.send(ERROR_MSG +"wrong message type " + msg)
+ else:
+ states[clientsock] = msg_types[msg]
+ clientsock.send(ACK_MSG)
+ #else:
+ print states[clientsock]
+
+ if states[clientsock] == WAITING_START_DATA:
+ bt_client_data = recv_pickled_data(clientsock)
+ if(DEBUG):
+ print "Server: received message:\n", msg
+ client_pid = start_bt_client(bt_client_data)
+ clientsock.send(ACK_MSG +" "+ str(client_pid))
+
+ elif states[clientsock] == WAITING_STOP_DATA:
+ client_pid = recv_pickled_data(clientsock)
+ if(DEBUG):
+ print "Server: received message:\n", msg
+ stop_bt_client(client_pid)
+ clientsock.send(ACK_MSG)
+
+ elif states[clientsock] == WAITING_STATUS_DATA:
+ config = recv_pickled_data(clientsock)
+ clientsock.send(ACK_MSG)
+
+ states[clientsock] = WAITING_MSG_TYPE
+
+ # clientsock.recv(BUFFER_SIZE)
+ # recv_pickled_data(clientsock)
+ clientsock.close()
class MyDaemon(Daemon):
def run(self):