Интересная задачка
Попробовал ваш пример, только немного переделал под себя. Зачем стучаться к вашему серверу, если все равно ничего не слать. Стучусь к домашнему веб серверу:
#!/usr/bin/env python
# -*-coding: utf-8 -*-
# vim: sw=4 ts=4 expandtab ai
# pylint: disable-msg=C0301
import socket
import threading
import time
class client(threading.Thread):
HOST = "192.168.0.1"
PORT = 80
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def connect(self):
self.s.connect((self.HOST, self.PORT))
print "connect true"
return
def run(self):
self.connect()
return
print "thread 1"
c1 = client()
c1.start()
time.sleep(30)
print "thread 2"
c2 = client()
c2.start()
Тоже выдает ошибку, только немного другую:
alex@kubu-book:~/development/PYTHON_projects$ python ~/socks_th0.py
thread 1
connect true
thread 2
Exception in thread Thread-2:
Traceback (most recent call last):
File "/usr/lib/python2.6/threading.py", line 532, in __bootstrap_inner
self.run()
File "/home/alex/socks_th0.py", line 22, in run
self.connect()
File "/home/alex/socks_th0.py", line 17, in connect
self.s.connect((self.HOST, self.PORT))
File "<string>", line 1, in connect
error: [Errno 106] Transport endpoint is already connected
В сети в это время происходит вот что:
alex@kubu-book:~/development/PYTHON_projects$ sudo tcpdump -n host 192.168.0.1 and tcp and port 80
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes
22:08:41.155830 IP 192.168.0.5.51828 > 192.168.0.1.80: Flags [S], seq 1150385388, win 5840, options [mss 1460,sackOK,TS val 203898 ecr 0,nop,wscale 6], length 0
22:08:41.156080 IP 192.168.0.1.80 > 192.168.0.5.51828: Flags [S.], seq 2554555935, ack 1150385389, win 5792, options [mss 1460,sackOK,TS val 151545188 ecr 203898,nop,wscale 5], length 0
22:08:41.156125 IP 192.168.0.5.51828 > 192.168.0.1.80: Flags [.], ack 1, win 92, options [nop,nop,TS val 203898 ecr 151545188], length 0
22:08:44.153486 IP 192.168.0.1.80 > 192.168.0.5.51828: Flags [S.], seq 2554555935, ack 1150385389, win 5792, options [mss 1460,sackOK,TS val 151545938 ecr 203898,nop,wscale 5], length 0
22:08:44.153536 IP 192.168.0.5.51828 > 192.168.0.1.80: Flags [.], ack 1, win 92, options [nop,nop,TS val 204647 ecr 151545938,nop,nop,sack 1 {0:1}], length 0
22:08:50.153830 IP 192.168.0.1.80 > 192.168.0.5.51828: Flags [S.], seq 2554555935, ack 1150385389, win 5792, options [mss 1460,sackOK,TS val 151547438 ecr 204647,nop,wscale 5], length 0
22:08:50.153879 IP 192.168.0.5.51828 > 192.168.0.1.80: Flags [.], ack 1, win 92, options [nop,nop,TS val 206147 ecr 151547438,nop,nop,sack 1 {0:1}], length 0
22:09:02.354540 IP 192.168.0.1.80 > 192.168.0.5.51828: Flags [S.], seq 2554555935, ack 1150385389, win 5792, options [mss 1460,sackOK,TS val 151550488 ecr 206147,nop,wscale 5], length 0
22:09:02.354591 IP 192.168.0.5.51828 > 192.168.0.1.80: Flags [.], ack 1, win 92, options [nop,nop,TS val 209198 ecr 151550488,nop,nop,sack 1 {0:1}], length 0
22:09:11.194953 IP 192.168.0.5.51828 > 192.168.0.1.80: Flags [F.], seq 1, ack 1, win 92, options [nop,nop,TS val 211408 ecr 151550488], length 0
22:09:11.195511 IP 192.168.0.1.80 > 192.168.0.5.51828: Flags [F.], seq 1, ack 2, win 181, options [nop,nop,TS val 151552698 ecr 211408], length 0
22:09:11.195558 IP 192.168.0.5.51828 > 192.168.0.1.80: Flags [.], ack 2, win 92, options [nop,nop,TS val 211408 ecr 151552698], length 0
^C
12 packets captured
12 packets received by filter
0 packets dropped by kernel
т е как я и предполагал второй сокет выходит с того же самого порта, что и первый - это и порождает такую ошибку. Причем серверу на той стороне это тоже как-то не нравится(я в wireshark покопался в пакетах)
Немного переделал код -
#!/usr/bin/env python
# -*-coding: utf-8 -*-
# vim: sw=4 ts=4 expandtab ai
# pylint: disable-msg=C0301
import socket
import threading
import time
class client(threading.Thread):
def connect(self):
HOST = "192.168.0.1"
PORT = 80
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
print "connect true"
return
def run(self):
self.connect()
return
print "thread 1"
client().start()
time.sleep(2)
print "thread 2"
client().start()
Теперь он отрабатывает как надо -
alex@kubu-book:~/development/PYTHON_projects$ python ./socks_th.py
thread 1
connect true
thread 2
connect true
И на сетевом уровне тоже все как полагается -
alex@kubu-book:~/development/PYTHON_projects$ sudo tcpdump -n host 192.168.0.1 and tcp and port 80
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes
22:09:58.224501 IP 192.168.0.5.51836 > 192.168.0.1.80: Flags [S], seq 2368199672, win 5840, options [mss 1460,sackOK,TS val 223165 ecr 0,nop,wscale 6], length 0
22:09:58.224720 IP 192.168.0.1.80 > 192.168.0.5.51836: Flags [S.], seq 3761446025, ack 2368199673, win 5792, options [mss 1460,sackOK,TS val 151564454 ecr 223165,nop,wscale 5], length 0
22:09:58.224760 IP 192.168.0.5.51836 > 192.168.0.1.80: Flags [.], ack 1, win 92, options [nop,nop,TS val 223165 ecr 151564454], length 0
22:09:58.225079 IP 192.168.0.5.51836 > 192.168.0.1.80: Flags [F.], seq 1, ack 1, win 92, options [nop,nop,TS val 223165 ecr 151564454], length 0
22:09:58.225634 IP 192.168.0.1.80 > 192.168.0.5.51836: Flags [F.], seq 1, ack 2, win 181, options [nop,nop,TS val 151564454 ecr 223165], length 0
22:09:58.225672 IP 192.168.0.5.51836 > 192.168.0.1.80: Flags [.], ack 2, win 92, options [nop,nop,TS val 223165 ecr 151564454], length 0
22:10:00.227030 IP 192.168.0.5.51837 > 192.168.0.1.80: Flags [S], seq 2392468491, win 5840, options [mss 1460,sackOK,TS val 223666 ecr 0,nop,wscale 6], length 0
22:10:00.227268 IP 192.168.0.1.80 > 192.168.0.5.51837: Flags [S.], seq 3794847646, ack 2392468492, win 5792, options [mss 1460,sackOK,TS val 151564955 ecr 223666,nop,wscale 5], length 0
22:10:00.227307 IP 192.168.0.5.51837 > 192.168.0.1.80: Flags [.], ack 1, win 92, options [nop,nop,TS val 223666 ecr 151564955], length 0
22:10:00.227470 IP 192.168.0.5.51837 > 192.168.0.1.80: Flags [F.], seq 1, ack 1, win 92, options [nop,nop,TS val 223666 ecr 151564955], length 0
22:10:00.227942 IP 192.168.0.1.80 > 192.168.0.5.51837: Flags [F.], seq 1, ack 2, win 181, options [nop,nop,TS val 151564955 ecr 223666], length 0
22:10:00.227989 IP 192.168.0.5.51837 > 192.168.0.1.80: Flags [.], ack 2, win 92, options [nop,nop,TS val 223666 ecr 151564955], length 0
^C
12 packets captured
12 packets received by filter
0 packets dropped by kernel
т е выходит с разных портов (51836 и 51837).
В данном феномене я еще не разобрался. такое ощущение, что инициализация объекта client происходит только один раз. Вероятно threading просто делает fork первого вызванного процесса/класса. Сейчас покопаюсь в книжном примере, приведенном вами выше.
Вероятно правильным решением будет отдельть объект, создающий socket от объекта, создающего новые потоки. Сделать 2 разных объекта.
PS
yurtaev
Пока копаю в документаций по сокетам, но не чего пока не нашёл.
Копатся надо в документации по threading относительно fork.