import sys from chat_server import ChatServer import time #The line means that we allow you to connect with any host (any IP and Hostname). #You can explicitly write a localhost or 127.0.0.1, then it will only work on one computer. server = ChatServer(5000, '10.40.27.236') server.start() try: while True: time.sleep(1) except KeyboardInterrupt: server.stop()
from chat_client import ChatClient from chat_server import ChatServer import time class ChatApp(): def __init__(self): self.server = ChatServer() self.client = ChatClient() def setup(): pass if __name__ == "__main__": server = ChatServer() clients = [ChatClient() for i in range(5)] server.start() for c in clients: c.connect() for c in clients: c.say_hello() time.sleep(3) server.stop()
class ChatServerTest(unittest.TestCase): """ Provides tests for the ChatServer application. """ HOST = _HOST PORT = _PORT RECV_BUFFER = _RECV_BUFFER RECV_MSG_LEN = _RECV_MSG_LEN def setUp(self): """ Sets up the test environment by running a new ChatServer thread. """ self.chat_server = ChatServer(self.HOST, self.PORT) self.chat_server.start() time.sleep(1) # Gives the client the time for connecting to the server def _get_fake_client(self): """ Returns a fake client. :return: a socket connected with the known (host, port) pair """ fake_client = socket.socket() fake_client.settimeout(1) fake_client.connect((self.HOST, self.PORT)) return fake_client def test_connection(self): """ Tests the client-server connection. """ fake_client = self._get_fake_client() fake_client.close() def _get_enter_message(self, socket_name): """ Given the pair (host, port), returns the message the server should broadcast to all the clients each time a new client connects. :param socket_name: the (host, port) pair related to the client connection :return: the message broadcast by the server when a new client connects """ return "\n[%s:%s] entered the chat room\n" % socket_name def _get_broadcast_message(self, socket_name, msg): """ Given the pair (host, port) and a message, returns the message the server should broadcast to all the clients. :param socket_name: the (host, port) pair related to the client connection :param msg: the message sent by the client :return: the message broadcast by the server """ return "\r" + '<' + str(socket_name) + '> ' + msg def _get_packed_length(self, msg): """ Given a message, return its packed length. :param msg: the message :return: the packed length of the message """ return struct.pack('>I', len(msg)) def test_broadcast(self): """ Tests the message broadcasting performed by the server. """ fc1 = self._get_fake_client() # The first client connects fc2 = self._get_fake_client() # The second client connects fc2_enter_msg = self._get_enter_message(fc2.getsockname()) fc2_msg_pack_len = self._get_packed_length(fc2_enter_msg) self.assertEqual(fc1.recv(self.RECV_MSG_LEN), fc2_msg_pack_len) self.assertEqual(fc1.recv(self.RECV_BUFFER), fc2_enter_msg) fc3 = self._get_fake_client() # The third client connects fc3_enter_msg = self._get_enter_message(fc3.getsockname()) fc3_msg_pack_len = self._get_packed_length(fc3_enter_msg) self.assertEqual(fc1.recv(self.RECV_MSG_LEN), fc3_msg_pack_len) self.assertEqual(fc1.recv(self.RECV_BUFFER), fc3_enter_msg) self.assertEqual(fc2.recv(self.RECV_MSG_LEN), fc3_msg_pack_len) self.assertEqual(fc2.recv(self.RECV_BUFFER), fc3_enter_msg) fc3_orig_msg = 'Hello' fc3_orig_msg_packed_len = self._get_packed_length(fc3_orig_msg) fc3.send(fc3_orig_msg_packed_len + fc3_orig_msg) # The third client sends a message fc3_broadcast_msg = self._get_broadcast_message( fc3.getsockname(), fc3_orig_msg) fc3_broadcast_msg_pack_len = self._get_packed_length(fc3_broadcast_msg) self.assertEqual(fc1.recv(self.RECV_MSG_LEN), fc3_broadcast_msg_pack_len) self.assertEqual(fc1.recv(self.RECV_BUFFER), fc3_broadcast_msg) self.assertEqual(fc2.recv(self.RECV_MSG_LEN), fc3_broadcast_msg_pack_len) self.assertEqual(fc2.recv(self.RECV_BUFFER), fc3_broadcast_msg) fc1.close() fc2.close() fc3.close() def test_heavy_broadcast(self): """ Tests the message broadcasting performed by the server when big messages are involved. """ fc1 = self._get_fake_client() # The first client connects fc2 = self._get_fake_client() # The second client connects fc2_enter_msg = self._get_enter_message(fc2.getsockname()) fc2_msg_pack_len = self._get_packed_length(fc2_enter_msg) self.assertEqual(fc1.recv(self.RECV_MSG_LEN), fc2_msg_pack_len) self.assertEqual(fc1.recv(self.RECV_BUFFER), fc2_enter_msg) fc2_orig_msg = os.urandom(10000) # Creates a message of 10000 bytes fc2_orig_msg_packed_len = self._get_packed_length(fc2_orig_msg) fc2.send(fc2_orig_msg_packed_len + fc2_orig_msg) # The second client sends an heavy message fc2_broadcast_msg = self._get_broadcast_message( fc2.getsockname(), fc2_orig_msg) fc2_broadcast_msg_pack_len = self._get_packed_length(fc2_broadcast_msg) self.assertEqual(fc1.recv(self.RECV_MSG_LEN), fc2_broadcast_msg_pack_len) fc2_receipt_message = '' for _ in xrange( 3 ): # Expecting 3 chunks of 4096 bytes ( ceil [10000 bytes / 4096 bytes] = 3 ) fc2_receipt_message += fc1.recv(self.RECV_BUFFER) self.assertEqual(fc2_receipt_message, fc2_broadcast_msg) fc1.close() fc2.close() def tearDown(self): """ Clears the test environment by stopping the server. """ time.sleep( 1) # Gives the client the time for disconnecting from the server self.chat_server.stop()