def main(): server = Server() server.initialize_socket() while True: client_socket = server.connect_clients() c = ClientHandler(client_socket, server.connected_client_list) c.start()
def start(self): logging.info('Listening on port {}.'.format(listenPort)) while True: try: (clientSock, (address, port)) = self.sock.accept() logging.info('Connecting to {}.'.format(address)) clientHandler = ClientHandler(clientSock) clientHandler.start() except socket.error as err: logging.error('Encountered socket error: {}.'.format(err))
def entry(self): listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM) listener.bind(('127.0.0.1', config.LISTEN_PORT)) listener.listen() while True: client, _ = listener.accept() if win32event.WaitForSingleObject(self.stop_event, 1) == win32event.WAIT_OBJECT_0: break t = ClientHandler(client) t.start()
def start(self): clients = [] try: while True: client_socket = None print "waiting clients..." client_socket, client_addr = self.__s.accept() c = ClientHandler(client_socket, client_addr) c.set_sessions(self.sess_names) clients.append(c) c.start() except KeyboardInterrupt: print "Ctrl+C" self.__s.close() finally: if client_socket != None: client_socket.close() self.__s.close() self.__s.close() map(lambda x: x.join(), clients)
class Client(QtWidgets.QWidget): handler: ClientHandler to_send: socket.socket # Конструктор: построение визуальных компонентов формы def __init__(self, parent=None, *args, **kwargs): super().__init__(parent, *args, **kwargs) # Задание имени файла self.setWindowTitle('Клиент передачи файлов') # Задание фиксированных размеров окна self.setFixedSize(510, 120) # Текстовое поле пути self.path = QtWidgets.QLineEdit() self.path.setAlignment(QtCore.Qt.AlignCenter) self.path.setPlaceholderText('Путь к файлу') # Кнопка выбора файла self.browse_button = QtWidgets.QPushButton('Выбрать файл') # Контейнер компонент, связанных с выбором файла self.path_box = QtWidgets.QHBoxLayout() self.path_box.addWidget(self.path) self.path_box.addWidget(self.browse_button) # Текстовое поле адреса self.host = QtWidgets.QLineEdit() self.host.setMinimumWidth(150) self.host.setPlaceholderText('Хост') self.host.setAlignment(QtCore.Qt.AlignCenter) self.host.setText(socket.gethostname()) # Числовое поле порта self.port = QtWidgets.QSpinBox() self.port.setMaximum(2**16) self.port.setMinimum(1) self.port.setValue(8888) self.port.setMaximumWidth(100) # Кнопки подключения и отключения от сервера self.connection_button = QtWidgets.QPushButton('Подключение') self.disconnection_button = QtWidgets.QPushButton('Отключение') # Контейнер подключения self.connection_box = QtWidgets.QHBoxLayout() self.connection_box.addWidget(self.host) self.connection_box.addWidget(self.port) self.connection_box.addWidget(self.connection_button) self.connection_box.addWidget(self.disconnection_button) # Кнопка отправки сообщения self.send_button = QtWidgets.QPushButton('Отправить') # Фоновый контейнер self.central_layout = QtWidgets.QVBoxLayout() self.central_layout.addLayout(self.path_box) self.central_layout.addLayout(self.connection_box) self.central_layout.addWidget(self.send_button) # Задания фокуса для окна self.setFocus() self.setLayout(self.central_layout) self.block_controls(False) # Задание обработок нажатия клавиш self.browse_button.clicked.connect(self.browse) self.connection_button.clicked.connect(self.connection) self.disconnection_button.clicked.connect(self.disconnection) # Блокировка/разблокировка компонент, в зависимости от состояния подключения def block_controls(self, connected): self.connection_button.setDisabled(connected) self.host.setDisabled(connected) self.port.setDisabled(connected) self.disconnection_button.setEnabled(connected) self.send_button.setEnabled(connected) # Выбор файла def browse(self): # Открытие диалогового окна, получение адреса selection = QtWidgets.QFileDialog.getOpenFileUrl(parent=self, caption='Выбор файла', filter='All (*)') file_path = selection[0].toLocalFile() # Запись в строку выбранного пути файла self.path.setText(file_path) # Соединение с сервером def connection(self): self.block_controls(True) # Инициализация потока, работающего с сокетами self.handler = ClientHandler( host=self.host.text( ), # Передача параметров хоста (с текстового поля) port=self.port.value() # Передача параметров порта ) # Задание событию нажатия кнопки "Отправить" действия по отправке файла self.handler.for_receive.connect( lambda sock: self.send_button.clicked.connect( partial(self.send, sock=sock))) # Задание событию получения файла с потока обработки в виде метода self.handler.file_sending.connect(self.receive) self.handler.start() # Запуск потока # Отсоединение def disconnection(self): self.block_controls(False) # Убийство потока с сокетом self.handler.terminate() # Отправка файла def send(self, sock): path = self.path.text() # Получение пути файла с текстового поля file_name = os.path.basename(path) # Извлечение имени файла с пути file_content = open( path, 'rb').read() # Чтение выбранного файла в бинарном виде # Преобразование кортежа из имени и содержания файла в массив байт message = pickle.dumps((file_name, file_content)) # Отправка сообщения (с характерной обёрткой) на сервер # Обёртка нужна, чтобы определить полноту полученного сообщения (оно отправляется по частям по 1024 байт) sock.send(b'<begin>' + message + b'<end>') # Получение файла @staticmethod def receive(file): yes = 16384 # Код, возвращаемый диалоговым окном при положительном ответе пользователя confirm = QtWidgets.QMessageBox.question( None, 'Подтверждение сохранения файла', 'Был получен новый файл. Вы желаете его сохранить?', buttons=QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, defaultButton=QtWidgets.QMessageBox.Yes) if confirm == yes: name, content = pickle.loads( file ) # Извлечение имени и содержания файла и полученного сообщения dia = QtWidgets.QFileDialog() # Инициализация диалога dia.setDefaultSuffix( name.split('.') [1]) # Подписание расширения получаемого файла при сохранении dia.setAcceptMode(QtWidgets.QFileDialog.AcceptSave ) # Вид диалогового окна - сохранение dia.setLabelText(QtWidgets.QFileDialog.FileType, name.split('.')[1]) # if dia.exec(): # Если результат диалогового окна непустой save_path = dia.selectedFiles()[ 0] # Получение пути выбранного файла file = open(save_path, 'wb') # Открытие (создание) файла в бинарном виде file.write(content) # Запись в файл содержимого file.close() # Прекращение работы с файлом