VII Python(9)socket编程
VII Python(9)socket編程
?
socket編程:
網絡基礎;
TCP/IP;
socket模型;
python socket C/S開發;
非阻塞(select、poll、epoll)
?
網絡基礎:
?
OSI七層協議、TCP/IP分層
注:
物理層(數據之間比特流的傳輸、物理接口、電氣特性;硬件接口標準,如RJ45水晶頭、無線網絡傳輸802.11b等);
數據鏈路層(組幀,進行硬件地址尋址,差錯校驗等功能;ARP、RARP;單個鏈路上數據的傳輸,如傳輸依賴的是光纖、雙絞線、還是無線等方式);
網絡層(進行邏輯地址尋址,實現不同網絡之間的路由選擇;ICMP、IP、IGMP;定義了端到端包的封裝方式,分片傳輸,如物理層的傳輸媒介傳輸單元的大小控制(通常網卡屬性上有單元大小,一般默認是1460長度一個單位),還定義了網絡中節點的邏輯位置(邏輯坐標));
傳輸層(可靠與不可靠傳輸,傳輸前的錯誤檢測、流控;TCP、UDP;網絡中數據的傳輸和控制,如tcp有連接狀態,保證數據傳輸無差錯,udp無連狀態,終端A只發送不管終端B是否收到,負責處理整個數據流拆成多個包時組裝次序的過程);
會話層(建立、管理、中止會話;決定了如何控制開始和結束的端對端的會話);
表示層(數據的表示、安全、壓縮;定義傳輸的數據格式,ASCII還是binary方式);
應用層(用戶接口;計算機中通信的具體應用,如Email、httpd等);
?
TCP三次握手、四次揮手:
TCP finite statemachine(FSM):
注:
CLOSED(there is no connection);
LISTEN(passive openreceived;waiting for SYN);
SYN-SENT(SYN sent;waiting forACK);
SYN-RCVD(SYN+ACK sent;waiting forACK);
ESTABLISHED(connectionestablished;data transfer in progress);
FIN-WAIT1(first FIN sent;waiting forACK);
FIN-WAIT2(ACK to first FINreceived;waiting for second FIN);
CLOSE-WAIT(first FIN received,ACK sent;waiting forapplication to close);
TIME-WAIT(second FIN received,ACK sent;waiting for2MSL(maximum segment lifetime,120s) timeout);
LAST-ACK(seconf FIN sent;waiting forACK);
CLOSING(both sides havedecided to close simultaneously)
?
?
socket C/S模式網絡開發:
網絡中不同主機間進程的交互;
client connect() 連接server-side時會隨機用一個port號;
socket套接字,用于描述IP:PORT,是一個通信鏈的句柄handler,應用程序通常通過socket向網絡發出請求或者應答網絡請求;socket起源于Unix,而Unix/Linux基本哲學之一是“一切皆文件”,對于文件用“打開、讀寫、關閉”模式來操作,socket就是該模式的一個體現,即是一種特殊的文件,一些socket函數就是對其進行的“r/wIO、打開、關閉”);
socket和file的區別(file是針對某個指定的文件進行“打開、讀寫、關閉”;而socket是針對server-side和client-side進行“打開、讀寫、關閉”);
?
?
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)? ?#(創建對象)
參數一,地址簇:
AF_INET為ipv4地址;
AF_INET6為ipv6地址;
AF_UNIX只能用于單一的Unix系統連接;
參數二,類型:
SOCK_STREAM指tcp協議默認;
SOCK_DGRAM指udp;
SOCK_RAW原始套接字,普通的套接字無法處理ICMP、IGMP等網絡報文,而SOCK_RAW可以,而且SOCK_RAW也可處理特殊的IPv4報文,另利用原始套接字,可通過IP_HDRINCL套接字選項由用戶構造IP頭;
參數三,協議:
0(默認,與特定的家族相關的協議,若是0系統會根據地址格式和套接類別自動選擇一個合適的協議);
?
sock.setblocking(bool)?? #(是否blocking,默認為True,如果設置False那accept和recv時一旦無數據則會報錯)
?
sock.setsockopt(level,option,value)?? #(設置套接字選項,level是被設置的選項的級別,若要想在套接字上設置level必須為SOL_SOCKET,在此級別下option有眾多選項其中SO_REUSEADDR表示打開或關閉地址利用功能,value為0表示關閉,非0打開;SO_DEBUG表示打開或關閉調試信息;SO_DONTROUTE表示打開或關閉路由查找功能;SO_BROADCAST表示允許或禁止發送廣播數據;SO_SNDBUF設置發送緩沖區的大小,有上下限,下限為2048byte,上限為256*(size of (struct sk_buff)+256))
?
sock.bind(address)?? #(將套接字綁定到地址,address的格式取決于地址族,在AF_INET下,以tuple的形式表示地址(IP,port))
?
sock.listen(backlog)?? #(開始監聽傳入連接,backlog指定在拒絕連接之前可以掛起的最大連接數量,backlog若為5表示內核已經接到了連接請求,但服務器還沒有調用accept進行處理的連接個數最大為5,這個值不能無限大,因為要在內核中維護連接隊列)
?
sock.accept()?? #(接受連接并返回(conn,address),其中conn是新的套接字對象,可以用來接收和發送數據,address是連接client的地址,接收tcp client的連接以blocking阻塞式等待連接的到來)
?
sock.recv(bufsize[,flag])?? #(接收套接字的數據,數據以字符串形式返回,bufsize指定最多可以接收的數量,flag提供有關消息的其它信息,通常可忽略)
?
sock.recvfrom(bufsize[,flag])?? #(與sock.recv(bufsize[,flag])類似,不過另有返回值(data,address),data是包含接收數據的字符串,address是發送數據的套接字地址)
?
sock.send(string[,flag])?? #(將數據string發送到連接的套接字,返回值是要發送的字節數量,該數量可能小于string的字節大小即可能未將指定內容全部發送)
?
sock.sendall(string[,flag])?? #(將數據string發送到連接的套接字,但在返回之前會嘗試發送所有數據,成功返回None,失敗則會拋出異常)
?
sock.sendto(string[,flag],address)?? #(將數據string發送到套接字,address的形式是(ip,port)的tuple,指定遠程地址,返回值是發送的字節數,該函數主要用于udp協議)
?
sock.close()?? #(關閉套接字)
?
sock.connect(address)?? #(連接到address處的套接字,一般address的格式為tuple,(IP orhostname,port),如果連接出錯,返回socket.error錯誤)
?
sock.connect_ex(address)?? #(與sock.connect(address)功能相同,只不過多了返回值,連接成功時返回0,連接失敗時返回非0編碼,例如10061)
?
sock.settimeout(timeout)? ?#(設置套接字操作的超時期timeout是一個浮點數,單位秒,值為None表示沒有超時期,一般超時期應在剛創建套接字時設置,因為它們可能用于連接的操作,例如client連接時最多等待5s)
?
sock.getpeername()?? #(返回連接套接字的遠程地址,返回值通常是tuple(ip,port))
?
sock.getsockname()?? #(返回套接字自己的地址,通常是tuple(ip,port))
?
sock.fileno()?? #(套接字的文件描述符fd)
?
?
socket高級應用,IO多路復用(指通過一種機制可以監視多個描述符,一旦某個描述符就緒(一般是讀就緒或寫就緒),能夠通知程序進行相應的讀寫操作);Linux中的select、poll、epoll都是IO多路復用的機制):
select(通過select()系統調用來監視多個文件描述符的數組,當select返回后,該數組中就緒的文件描述符便會被內核修改標志位,使得進程可以獲得這些文件描述符從而進行后續的讀寫操作;此策略的缺點,單個進程能夠監視的文件描述符的數量存在最大限制,Linux默認為1024,隨著文件描述符數量的增大,其復制的開銷也線性增長);
poll(與select類似,但沒有文件描述符的限制);
epoll(內核直接支持,基于事件驅動event-driven(分兩部分:注冊事件和觸發事件);
?
Python中有select模塊,該模塊提供了select、poll、epoll這三種方法)
?
rs,ws,xs=select.select(rlist,wlist,xlist[,timeout])?? #(select方法用來監視文件句柄,如果句柄發生變化,則獲取該句柄;括號中前三個參數必須,返回三個列表)
當rlist中的句柄發生可讀時(accept和read),則獲取發生變化的句柄并添加到rs中;
當wlist中含有句柄時,則將該序列中所有的句柄添加到ws中;
當xlist中的句柄發生錯誤時,則將該發生錯誤的句柄添加到xs中;
當timeout未設置select會一直blocking,直到監聽的句柄發生變化;當timeout為1時,如果監聽的句柄無任何變化則select會阻塞1s之后返回三個空列表,如果監聽的句柄有變化則直接執行;
?
?
In [1]: import socket
In [2]: help(socket)
Functions:
???socket() -- create a new socket object
???socketpair() -- create a pair of new socket objects [*]
???fromfd() -- create a socket object from an open file descriptor [*]
???gethostname() -- return the current hostname
???gethostbyname() -- map a hostname to its IP number
???gethostbyaddr() -- map an IP number or hostname to DNS info
???getservbyname() -- map a service name and a protocol name to a portnumber
???getprotobyname() -- map a protocol name (e.g. 'tcp') to a number
???ntohs(), ntohl() -- convert 16, 32 bit int from network to host byteorder
???htons(), htonl() -- convert 16, 32 bit int from host to network byteorder
???inet_aton() -- convert IP addr string (123.45.67.89) to 32-bit packedformat
???inet_ntoa() -- convert 32-bit packed format IP to string (123.45.67.89)
???ssl() -- secure socket layer support (only available if configured)
???socket.getdefaulttimeout() -- get the default timeout value
???socket.setdefaulttimeout() -- set the default timeout value
???create_connection() -- connects to an address, with an optional timeoutand
?????????????????????????? optional sourceaddress.
In [3]: print dir(socket)
['AF_APPLETALK', 'AF_ASH', 'AF_ATMPVC','AF_ATMSVC', 'AF_AX25', 'AF_BRIDGE', 'AF_DECnet', 'AF_ECONET', 'AF_INET', 'AF_INET6','AF_IPX',……'PACKET_OUTGOING', 'PF_PACKET', 'RAND_add', 'RAND_egd','RAND_status', 'SHUT_RD', 'SHUT_RDWR', 'SHUT_WR', 'SOCK_DGRAM','SOCK_RAW', 'SOCK_RDM', 'SOCK_SEQPACKET', 'SOCK_STREAM','SOL_IP', 'SOL_SOCKET', 'SOL_TCP', 'SOL_TIPC', 'SOL_UDP', 'SOMAXCONN', ……'create_connection','errno', 'error', 'fromfd', 'gaierror', 'getaddrinfo', 'getdefaulttimeout','getfqdn', 'gethostbyaddr', 'gethostbyname', 'gethostbyname_ex', 'gethostname','getnameinfo', 'getprotobyname', 'getservbyname', 'getservbyport', 'has_ipv6','herror', 'htonl', 'htons', 'inet_aton', 'inet_ntoa', 'inet_ntop', 'inet_pton','m', 'meth', 'ntohl', 'ntohs', 'os', 'p', 'partial', 'setdefaulttimeout', 'socket', 'socketpair', 'ssl', 'sslerror', 'sys','timeout', 'warnings']
In [4]: sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)??#(創建對象;參數一地址簇:AF_INET為ipv4地址,AF_INET6為ipv6地址,AF_UNIX只能用于單一的Unix系統連接;參數二類型:SOCK_STREAM指tcp協議默認,SOCK_DGRAM指udp)
In [5]: print dir(sock)
['__class__', '__delattr__', '__doc__','__format__', '__getattribute__', '__hash__', '__init__', '__module__','__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__','__sizeof__', '__slots__', '__str__', '__subclasshook__', '__weakref__','_sock', 'accept', 'bind', 'close', 'connect', 'connect_ex','dup', 'family', 'fileno', 'getpeername', 'getsockname', 'getsockopt','gettimeout', 'listen', 'makefile', 'proto', 'recv', 'recv_into', 'recvfrom', 'recvfrom_into', 'send', 'sendall', 'sendto', 'setblocking','setsockopt', 'settimeout', 'shutdown', 'type']
In [6]: help(sock.bind)?? #(server-side使用,對象綁定)
bind(...) method of socket._socketobjectinstance
???bind(address)
???Bind the socket to a local address.?For IP sockets, the address is a
???pair (host, port); the host must refer to the local host. For raw packet
???sockets the address is a tuple (ifname, proto [,pkttype [,hatype]])
In [7]: help(sock.listen)?? #(server-side使用,指定監聽多少個請求)
listen(...) method of socket._socketobjectinstance
???listen(backlog)
???Enable a server to accept connections.?The backlog argument must be at
???least 0 (if it is lower, it is set to 0); it specifies the number of
???unaccepted connections that the system will allow before refusing new
???connections.
In [8]: help(sock.accept)??#(server-side使用,sock.accpet()返回兩個參數,一個是建立連接的socket object和另一個是地址信息)
accept(self) method of socket._socketobjectinstance
???accept() -> (socket object, address info)
???Wait for an incoming connection.?Return a new socket representing the
???connection, and the address of the client.? For IP sockets, the address
???info is a pair (hostaddr, port).
In [9]:help(sock.recv) ??#(設置讀操作緩沖區大小,server-side和client-side都可使用,注意server-side使用時此項要在socket.accept()返回的那個socketobject上使用)
recv(...)
???recv(buffersize[, flags]) -> data
???Receive up to buffersize bytes from the socket.? For the optional flags
???argument, see the Unix manual.?When no data is available, block until
???at least one byte is available or until the remote end is closed.? When
???the remote end is closed and all data is read, return the empty string.
In [10]:help(sock.send) ??#(寫操作,server-side和client-side均可使用,注意server-side使用時要在socket.accept()返回的那個socketobject上使用)
send(...)
???send(data[, flags]) -> count
???Send a data string to the socket.?For the optional flags
???argument, see the Unix manual.?Return the number of bytes
???sent; this may be less than len(data) if the network is busy.
In [11]: help(sock.close)??#(server-side和client均可使用)
close(self, _closedsocket=<class'socket._closedsocket'>, _delegate_methods=('recv', 'recvfrom', 'recv_into','recvfrom_into', 'send', 'sendto'), setattr=<built-in function setattr>)method of socket._socketobject instance
???close()
???Close the socket.? It cannot beused after this call.
In [12]: help(sock.connect)?? #(用于client)
connect(...) method of socket._socketobjectinstance
???connect(address)
???Connect the socket to a remote address.?For IP sockets, the address
???is a pair (host, port).
In [13]: help(sock.getpeername)??#(用于client,返回連接的服務器地址)
getpeername(...) method ofsocket._socketobject instance
???getpeername() -> address info
???Return the address of the remote endpoint.? For IP sockets, the address
???info is a pair (hostaddr, port).
?
In [14]: help(sock.setblocking)?? #(server-side用,flag為false則是non-blocking,flag為True則是blocking)
setblocking(...) method ofsocket._socketobject instance
???setblocking(flag)
???Set the socket to blocking (flag is true) or non-blocking (false).
???setblocking(True) is equivalent to settimeout(None);
???setblocking(False) is equivalent to settimeout(0.0).
In [15]: help(sock.setsockopt)??#(server-side用)
setsockopt(...) method ofsocket._socketobject instance
???setsockopt(level, option, value)
???Set a socket option.? See the Unixmanual for level and option.
???The value argument can either be an integer or a string.
?
In [16]: import select
In [17]: print dir(select)
['EPOLLERR', 'EPOLLET', 'EPOLLHUP','EPOLLIN', 'EPOLLMSG', 'EPOLLONESHOT', 'EPOLLOUT', 'EPOLLPRI', 'EPOLLRDBAND','EPOLLRDNORM', 'EPOLLWRBAND', 'EPOLLWRNORM', 'PIPE_BUF', 'POLLERR', 'POLLHUP','POLLIN', 'POLLMSG', 'POLLNVAL', 'POLLOUT', 'POLLPRI', 'POLLRDBAND','POLLRDNORM', 'POLLWRBAND', 'POLLWRNORM', '__doc__', '__file__', '__name__','__package__', 'epoll', 'error', 'poll', 'select']
In [18]: help(select)
NAME
???select - This module supports asynchronous I/O on multiple filedescriptors.
FUNCTIONS
???poll(...)
???????Returns a polling object, which supports registering and
???????unregistering file descriptors, and then polling them for I/O events.
???select(...)
???????select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)
???????Wait until one or more file descriptors are ready for some kind of I/O.
???????The first three arguments are sequences of file descriptors to be waitedfor:
???????rlist -- wait until ready for reading
???????wlist -- wait until ready for writing
???????xlist -- wait for an ``exceptional condition''
???????If only one kind of condition is required, pass [] for the other lists.
???????A file descriptor is either a socket or file object, or a small integer
???????gotten from a fileno() method call on one of those.
???????The optional 4th argument specifies a timeout in seconds; it may be
???????a floating point number to specify fractions of seconds.? If it is absent
???????or None, the call will never time out.
???????The return value is a tuple of three lists corresponding to the firstthree
???????arguments; each contains the subset of the corresponding filedescriptors
???????that are ready.
?
In [19]: import Queue
In [20]: help(Queue)
NAME
???Queue - A multi-producer, multi-consumer queue.
???class Queue
????|? Create a queue object with agiven maximum size.
????|? get(self, block=True,timeout=None)
????|????? Remove and return an itemfrom the queue.
????|????? If optional args 'block' istrue and 'timeout' is None (the default),
????|????? block if necessary until anitem is available. If 'timeout' is
????|????? a non-negative number, itblocks at most 'timeout' seconds and raises
????|????? the Empty exception if noitem was available within that time.
????|????? Otherwise ('block' isfalse), return an item if one is immediately
????|????? available, else raise theEmpty exception ('timeout' is ignored
????|????? in that case).
????|? get_nowait(self)
????|????? Remove and return an itemfrom the queue without blocking.
????|?????
????|? ????Only get an item if one is immediatelyavailable. Otherwise
????|????? raise the Empty exception.
????|? put(self, item, block=True,timeout=None)
????|????? Put an item into the queue.
????|????? If optional args 'block' istrue and 'timeout' is None (the default),
????|????? block if necessary until afree slot is available. If 'timeout' is
????|????? a non-negative number, itblocks at most 'timeout' seconds and raises
????|????? the Full exception if nofree slot was available within that time.
????|????? Otherwise ('block' isfalse), put an item on the queue if a free slot
????|????? is immediately available,else raise the Full exception ('timeout'
????|????? is ignored in that case).
????|? put_nowait(self, item)
????|????? Put an item into the queuewithout blocking.
????|????? Only enqueue the item if afree slot is immediately available.
????|????? Otherwise raise the Fullexception.
In [21]: print dir(Queue)
['Empty', 'Full', 'LifoQueue','PriorityQueue', 'Queue', '__all__','__builtins__', '__doc__', '__file__', '__name__', '__package__', '_threading','_time', 'deque', 'heapq']
In [22]: print dir(Queue.Queue)
['__doc__', '__init__', '__module__','_get', '_init', '_put', '_qsize', 'empty', 'full', 'get','get_nowait', 'join', 'put', 'put_nowait','qsize', 'task_done']
?
?
舉例-version1(使用socket模塊實現C/S通信)
[root@localhost ~]# vim server_test.py
----------------script start-----------------
#!/usr/bin/python2.7
#
import socket
?
server=('10.96.20.113',20072)
?
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.bind(server)
sock.listen(5)
conn,address=sock.accept()
print 'connect by',address
while True:
???????data=conn.recv(1024)
???????if not data: break
???????print data
???????conn.send(data)
sock.close()
--------------------script end-----------------
[root@localhost ~]# vim client_test.py
--------------------script start---------------
#!/usr/bin/python2.7
#
import socket
?
server=('10.96.20.113',20072)
?
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.connect(server)
sock.send('hello')
data=sock.recv(1024)
print 'echo',data
sock.close()
---------------------script end------------------
[root@localhost ~]# python2.7 server_test.py ??#(分別在兩個終端上運行server-side和client-side)
connect by ('10.96.20.113', 48273)
hello
[root@localhost ~]# python2.7 client_test.py
echo hello
?
舉例-version2(使用socket模塊實現C/S通信)
[root@localhost ~]# vim client_test.py ??#(服務端與version1相同,只更改client)
-------------------script start-----------------
#!/usr/bin/python2.7
#
import socket
import time
?
server=('10.96.20.113',20072)
msg=['hello','everyone','welcome','to','my','territory']
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.connect(server)
for m in msg:
? ? ? ?sock.send(m)
???????data=sock.recv(1024)
???????print 'echo',data
???????time.sleep(2)
sock.close
-----------------------script end-----------------
[root@localhost ~]# python2.7 server_test.py ??#(分別在兩個窗口上運行server_test.py和client_test.py)
connect by ('10.96.20.113', 48275)
hello
everyone
welcome
to
my
territory
[root@localhost ~]# python2.7 client_test.py
echo hello
echo everyone
echo welcome
echo to
echo my
echo territory
[root@localhost ~]# python2.7 client_test.py ??#(再次運行client,由于server-side已不在運行,窗口已關閉,client運行時Connectionrefused拒絕連接)
Traceback (most recent call last):
?File "client_test.py", line 9, in <module>
???sock.connect(server)
?File "/usr/local/python2.7/lib/python2.7/socket.py", line 224,in meth
???return getattr(self._sock,name)(*args)
socket.error: [Errno 111] Connection refused
注:server-side不支持并發操作不能作為永久的伺服器;server-side沒有讀寫分離(I/O輸入輸出分離),有分離的話會提高并發能力
?
?
舉例(利用select模塊實現處理多個client請求)
[root@localhost ~]# vim server_test.py
-------------------script start--------------
#!/usr/bin/python2.7
#
import socket
import select
import Queue
?
server=('10.96.20.113',20072)
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.setblocking(False)
sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
sock.bind(server)
sock.listen(10)
rlists=[sock]
wlists=[]
msg_que={}
timeout=20
while rlists:
???????rs,ws,es=select.select(rlists,wlists,rlists,timeout)
???????if not (rs or ws or es):
??????????????? print 'timeout...'
??????????????? break
???????for s in rs:
??????????????? if s is sock:
??????????????????????? conn,addr=s.accept()
??????????????????????? print 'connect by',addr
??????????????????????? conn.setblocking(False)
??????????????????????? rlists.append(conn)
???????????????????????msg_que[conn]=Queue.Queue()
???????????????else:
??????????????????????? data=s.recv(1024)
??????????????????????? if data:
??????????????????????????????? print data
???????????????????????????????msg_que[s].put(data)
??????????????????????????????? if s not inwlists:
???????????????????????????????????????wlists.append(s)
??????????????????????? else:
??????????????????????????????? if s in wlists:
???????????????????????????????????????wlists.remove(s)
???????????????????????????????rlists.remove(s)
?????????????? ?????????????????s.close()
??????????????????????????????? del msg_que[s]
???????for s in ws:
??????????????? try:
???????????????????????msg=msg_que[s].get_nowait()
??????????????? except Queue.Empty:
??????????????????????? print 'msg empty'
???????????????????????wlists.remove(s)
??????????????? else:
??????????????????????? s.send(msg)
???????for s in es:
??????????????? print 'except',s.getpeername()
??????????????? if s in rlists:
??????????????????????? rlists.remove(s)
??????????????? if s in wlists:
??????????????????????? wlists.remove(s)
??????????????? s.close()
??????????????? del msg_que[s]
--------------------script end----------------
[root@localhost ~]# vim client_test.py
----------------------script start----------------
#!/usr/bin/python2.7
#
import socket
import time
?
server=('10.96.20.113',20072)
msg=['hello','everyone','welcome','to','my','territory']
socks=[]
?
for i in range(10):
???????sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
???????socks.append(sock)
for s in socks:
???????s.connect(server)
counter=0
for m in msg:
???????for s in socks:
??????????????? s.send('%d send %s' %(counter,m))
??????????????? counter+=1
???????for s in socks:
??????????????? data=s.recv(1024)
??????????????? print '%s echo %s' % (s.getpeername(),data)
??????????????? if not data:
??????????????????????? s.close()
???????time.sleep(2)
---------------------script end--------------------
[root@localhost ~]# python2.7 server_test.py ??#(在兩個終端上分別執行server_test.py和client_test.py)
connect by ('10.96.20.113', 48299)
connect by ('10.96.20.113', 48300)
connect by ('10.96.20.113', 48301)
connect by ('10.96.20.113', 48302)
connect by ('10.96.20.113', 48303)
connect by ('10.96.20.113', 48304)
connect by ('10.96.20.113', 48305)
connect by ('10.96.20.113', 48306)
connect by ('10.96.20.113', 48307)
connect by ('10.96.20.113', 48308)
……
58 send territory
59 send territory
……
msg empty
msg empty
msg empty
timeout...
[root@localhost ~]# python2.7 client_test.py
('10.96.20.113', 20072) echo 0 send hello
('10.96.20.113', 20072) echo 1 send hello
('10.96.20.113', 20072) echo 2 send hello
('10.96.20.113', 20072) echo 3 send hello
('10.96.20.113', 20072) echo 4 send hello
('10.96.20.113', 20072) echo 5 send hello
('10.96.20.113', 20072) echo 6 send hello
('10.96.20.113', 20072) echo 7 send hello
('10.96.20.113', 20072) echo 8 send hello
('10.96.20.113', 20072) echo 9 send hello
('10.96.20.113', 20072) echo 10 sendeveryone
……
('10.96.20.113', 20072) echo 57 sendterritory
('10.96.20.113', 20072) echo 58 sendterritory
('10.96.20.113', 20072) echo 59 sendterritory
轉載于:https://blog.51cto.com/jowin/1834189
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的VII Python(9)socket编程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android 部分机型GridView
- 下一篇: 装饰器模式与java.io包