В данном примере использованы переработанные и объединённые материалы с оффорума. Спасибо товарищам lvs и Hypnos. Код я очень подробно - чуть ли не каждую строку - откомментировал, так что отдельно описывать почти нечего.
На что стоит обратить внимание: сервер и клиент работают в raw (сырые данные) режиме, хотя в мануале приводят версию работы через датаграммы. Что нам даёт сырой режим? Мы можем приконнектиться к серверу любым приложением, пересылающим данные в сыром/текстовом виде. Например телнетом. Собственно телнетом мы и будем проверять работоспособность сервера. В командной строке: telnet 127.0.0.1 9099, ещё один вариант - пошутить над браузером. В методе readTask две закомментированные строки после self.cWriter.send(msg,conn) -раскомментируйте их, а self.cWriter.send(msg,conn) удалите или закомментируйте, т.е. приведите этот кусок к виду
Код #в качестве теста отправляем полученное сообщение обратно - эхо self.cWriter.send('HTTP/1.0 200 Ok\nContent-Type: text/html; charset=windows-1251\n\n<h1>Hellow World!</h1>',conn) self.cManager.closeConnection(conn)
и попробуйте вбить в браузере http://127.0.0.1:9099/ - браузер решит, что приконнектился к вебсерверу, а в консольке можно будет увидеть заголовок, отправленный браузером нашему "вебсерверу". Насчёт датаграмм - разговор, стоящий отдельной статьи - используя их, можно минимизировать трафик, однако потребуется дополнительная проверка, т.к. некорректный пакет данных может просто свалить сервер. И вообще я ленивый, поэтому мне, проще использовать какой-нибудь модуль сериализации и слать напрямую питоновские структуры в raw ).
По поводу клиентской части - она очень похожа на серверную, так что я даже не стал её комментировать - фактически все строки идентичны, только в клиенте их поменьше, ведь нам не нужно слушать порт и обслуживать кучу соединений - соединение у нас одно, а для чтения/записи данных мы используем те же классы и методы что и для сервера. Единственная, наверно, незнакомая строка self.myConnection = self.cManager.openTCPClientConnection(host, port, timeout) которой мы, собственно и устанавливаем соединение с сервером.
Архив с исходником здесь
|