Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Курсовая / serverTWO

.py
Скачиваний:
0
Добавлен:
12.02.2024
Размер:
6.42 Кб
Скачать
import sys, socket, datetime, threading, os
from PyQt5.QtCore import * 
from PyQt5.QtWidgets import *
from GUI.server_gui import Ui_MainWindow  # импорт сгенерированного файла
HOST = "127.0.0.1"
PORT = 9999

run = True# Флаг остановки дочерних потоков
servSocket = None
BUF_SIZE = 256# Размер буфера для получения сообшения

# функция для вывода идентификатора потоков процесса
def get_thread_ids():
    thread_ids = []
    for thread in threading.enumerate():
        thread_ids.append(thread.ident)
    return thread_ids
# функция для вывода идентификатора процесса
def get_process_id():
    return os.getpid()

# Обработка полученного сообщения
def threadFunc(servSocket, addr, window):
    with servSocket:
        answer = f'Клиент {addr} подключен'
        print(answer)
        window.addItem('Сервер: ', answer) # Выводится сообщение о подключении клиента через print и метод window.addItem(), который обновляет интерфейс приложения.
        
        while run:
            # Получение сообщения от Клиента
            try:
                data = servSocket.recv(BUF_SIZE).decode()

            except ConnectionError:
                print("Ошибка! Клиент отключился во время передачи сообщения!")
                break
            
            print(f"Получено: {data} от: {addr}")
            
            if not data:
                break
            
            # Добавление времени в ответное сообщение 
            now = datetime.datetime.now()
            answer = now.strftime("%d-%m-%Y %H:%M:%S")

            if(data == 'get process id'):
                process_id = str(get_process_id())
                answer += 'Идентификатор серверного процесса: ' + process_id

            if(data == 'get thread ids'):
                thread_ids = get_thread_ids()
                answer += 'Идентификаторы потоков серверного процесса: ' + ', '.join(str(thread_id) for thread_id in thread_ids)

            try:
                # Отправка ответа Клиенту
                servSocket.sendall(answer.encode())
                print(f"Отправлено: {answer} кому: {addr}")
                window.addItem('Сервер: ', answer)
            except ConnectionError:
                print("Ошибка! Клиент отключился во время передачи сообщения!")
                break

        answer = f'Клиент {addr} отключился'
        print(answer)
        window.addItem('Сервер: ', answer)

# Запуск сервера
def runServer():
    '''socket.AF_INET - это константа, которая указывает на использование сокета семейства IPv4.
    socket.SOCK_STREAM - это константа, которая указывает на использование потокового (TCP) сокета.
    socket.SOL_SOCKET - это уровень сокета, который указывает, что опция применяется к сокету в целом.
    socket.SO_REUSEADDR - это опция сокета, которая позволяет повторно использовать локальный адрес для привязки на серверной стороне, 
    даже если он все еще находится в состоянии TIME_WAIT после закрытия предыдущего соединения.
    '''  
    global HOST, PORT, thread_id
    thread_id = str(threading.get_ident())
    
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as serv_sock:
        serv_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        # Привязка сокета к указанному хосту (адресу) и порту  
        serv_sock.bind((HOST, PORT))
        serv_sock.listen(1)
        print("Сервер запущен")

        try:
            while True:
                global servSocket

                print("Ожидает подключения...")
                # Принятие подключения от клиента, возвращается сокет клиента и его адрес
                servSocket, addr = serv_sock.accept()
                # Создание и запуск нового потока для обработки клиента
                t = threading.Thread(target=threadFunc, args=(servSocket, addr, window))
                t.start()

        except KeyboardInterrupt:
            print("Сервер остановлен!")

        finally:
            global run
            run = False
            serv_sock.close()

# Пользовательский интерфейс
class mywindow(QMainWindow):
    def __init__(self):
        super(mywindow, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.setWindowTitle("Сервер 2")

    def addItem(self, str, data):
        self.ui.listWidget.addItem(str + data)
        
# Запуск сервера в главном потоке
if __name__ == '__main__':
    # Проверка на запушенный экземпляр приложения
    lockfile = QLockFile(QDir.tempPath() + '/server_2.lock')
    # Попытка блокировки файла блокировки (чтобы мог запускаться только 1 экземпляр сервера)
    if lockfile.tryLock(100):
        app = QApplication(sys.argv)
        
        window = mywindow()
        # Создание и запуск потока сервера в отдельном потоке
        serverThread = threading.Thread(None, runServer)
        serverThread.start()
        window.show()
        # Завершение программы вместе с выполнением цикла событий приложения
        sys.exit(app.exec_())
    else:
        print("Сервер 2 уже запущен!")



Соседние файлы в папке Курсовая