Прежде чем двигаться дальше, следует сказать о трех аспектах практического использования сокетов. Во-первых, такие клиент и сервер могут выполняться на любых двух подключенных к Интернету компьютерах, где установлен Python. Конечно, чтобы запускать клиенты и сервер на разных компьютерах, необходимы действующее соединение с Интернетом и доступ к тому компьютеру, на котором должен быть запущен сервер.
При этом не требуется дорогостоящего высокоскоростного соединения — при работе с сокетами Python довольствуется любым соединением, которое существует на компьютере, будь то выделенная линия T1, беспроводное подключение, кабельный модем или простое коммутируемое соединение. Кроме того, если у вас нет собственной учетной записи на собственном сервере, как у меня на сервере learning—python.com, запускайте примеры клиента и сервера на одном компьютере, localhost, как было показано выше, — для этого лишь требуется, чтобы компьютер разрешал использовать сокеты, что бывает почти всегда.
Во-вторых, модуль socket обычно возбуждает исключение при запросе чего-либо недопустимого. Например, неудачной будет попытка подключения к несуществующему серверу (или недоступному, если нет связи с Интернетом):
C:\…\PP4E\Internet\Sockets> python echo-client.py www.nonesuch.com hello Traceback (most recent call last):
File "echo-client.py", line 24, in <module>
sockobj.connect((serverHost, serverPort)) # соединение с сервером и… socket.error: [Errno 10060] A connection attempt failed because the connected
party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
(socket.error: [Ошибка 10060] Попытка соединения потерпела неудачу, потому что противоположная сторона не ответила в течение заданного интервала времени, или установленное соединение было разорвано, потому что другая сторона не смогла ответить)
Наконец, следите за тем, чтобы остановить процесс сервера, прежде чем запустить его заново, потому что иначе порт окажется занятым и вы получите другое исключение, как на моем удаленном компьютере сервера:
[…]$ ps -x
PID TTY STAT TIME COMMAND
5378 pts/0 S 0:00 python echo-server.py
22017 pts/0 Ss 0:00 -bash
26805 pts/0 R+ 0:00 ps -x
[…]$ python echo-server.py
Traceback (most recent call last):
File "echo-server.py", line 14, in <module>
sockobj.bind((myHost, myPort)) # связать с номером порта сервера socket.error: [Errno 10048] Only one usage of each socket address (protocol/ network address/port) is normally permitted
(socket.error: [Ошибка 10048] Только один сокет может быть связан с каждым адресом (протокол/сетевой адрес/порт))
В Linux сервер можно остановить несколькими нажатиями комбинации клавиш Ctrl—C (если он был запущен в фоновом режиме с &, сначала нужно перевести его на передний план командой fg):
[…]$ fg
python echo-server.py
Traceback (most recent call last):
File "echo-server.py", line 18, in <module>
connection, address = sockobj.accept() # ждать запроса
# очередного клиента KeyboardInterrupt
Как упоминалось выше, комбинация клавиш Ctrl—C не завершает сервер на моем компьютере с Windows 7. Чтобы завершить локальный постоянно выполняющийся процесс сервера в Windows, может потребоваться запустить Диспетчер задач (Task Manager) (то есть нажать комбинацию клавиш Ctrl—Alt—Delete), а затем завершить задачу Python, выбрав ее в появившемся списке процессов. Кроме того, в Windows можно просто закрыть окно консоли, где был запущен сервер, чтобы остановить его, но при этом будет потеряна история команд. В Linux можно также завершить работу сервера, запущенного в другом окне или в фоновом режиме, с помощью команды оболочки kill -9 pid, но использование комбинации Ctrl—C требует меньше нажатий на клавиши.
Использованная литература:
Марк Лутц — Программирование на Python, 4-е издание, II том, 2011