当前位置: 首页 > news >正文

VII Python(9)socket编程

socket编程:

网络基础;

TCP/IP

socket模型;

python socket C/S开发;

非阻塞(selectpollepoll

 

网络基础:

wKiom1einwWSruTnAABC2rDcZ1c769.jpg

 

OSI七层协议、TCP/IP分层

wKioL1einxGAI3FDAACUqmJqff0310.jpg

注:

物理层(数据之间比特流的传输、物理接口、电气特性;硬件接口标准,如RJ45水晶头、无线网络传输802.11b等);

数据链路层(组帧,进行硬件地址寻址,差错校验等功能;ARPRARP;单个链路上数据的传输,如传输依赖的是光纤、双绞线、还是无线等方式);

网络层(进行逻辑地址寻址,实现不同网络之间的路由选择;ICMPIPIGMP;定义了端到端包的封装方式,分片传输,如物理层的传输媒介传输单元的大小控制(通常网卡属性上有单元大小,一般默认是1460长度一个单位),还定义了网络中节点的逻辑位置(逻辑坐标));

传输层(可靠与不可靠传输,传输前的错误检测、流控;TCPUDP;网络中数据的传输和控制,如tcp有连接状态,保证数据传输无差错,udp无连状态,终端A只发送不管终端B是否收到,负责处理整个数据流拆成多个包时组装次序的过程);

会话层(建立、管理、中止会话;决定了如何控制开始和结束的端对端的会话);

表示层(数据的表示、安全、压缩;定义传输的数据格式,ASCII还是binary方式);

应用层(用户接口;计算机中通信的具体应用,如Emailhttpd等);

 

TCP三次握手、四次挥手:

wKiom1einyDzDQ13AACWezXjrgk455.jpg

TCP finite statemachineFSM):

wKiom1einyzASMtOAADdURJq2RM236.jpg

wKioL1einzihVncBAAC7NeU_G04978.jpg

注:

CLOSEDthere is no connection);

LISTENpassive openreceivedwaiting for SYN);

SYN-SENTSYN sentwaiting forACK);

SYN-RCVDSYN+ACK sentwaiting forACK);

ESTABLISHEDconnectionestablisheddata transfer in progress);

FIN-WAIT1first FIN sentwaiting forACK);

FIN-WAIT2ACK to first FINreceivedwaiting for second FIN);

CLOSE-WAITfirst FIN receivedACK sentwaiting forapplication to close);

TIME-WAITsecond FIN receivedACK sentwaiting for2MSLmaximum segment lifetime120s timeout);

LAST-ACKseconf FIN sentwaiting forACK);

CLOSINGboth sides havedecided to close simultaneously

 

 

socket C/S模式网络开发:

网络中不同主机间进程的交互;

client connect() 连接server-side时会随机用一个port号;

wKioL1ein0fBR9MPAACU53WJrJI777.jpg

socket套接字,用于描述IP:PORT,是一个通信链的句柄handler,应用程序通常通过socket向网络发出请求或者应答网络请求;socket起源于Unix,而Unix/Linux基本哲学之一是“一切皆文件”,对于文件用“打开、读写、关闭”模式来操作,socket就是该模式的一个体现,即是一种特殊的文件,一些socket函数就是对其进行的“r/wIO、打开、关闭”);

socketfile的区别(file是针对某个指定的文件进行“打开、读写、关闭”;而socket是针对server-sideclient-side进行“打开、读写、关闭”);

 

 

sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)   #(创建对象)

参数一,地址簇:

AF_INETipv4地址;

AF_INET6ipv6地址;

AF_UNIX只能用于单一的Unix系统连接;

参数二,类型:

SOCK_STREAMtcp协议默认;

SOCK_DGRAMudp

SOCK_RAW原始套接字,普通的套接字无法处理ICMPIGMP等网络报文,而SOCK_RAW可以,而且SOCK_RAW也可处理特殊的IPv4报文,另利用原始套接字,可通过IP_HDRINCL套接字选项由用户构造IP头;

参数三,协议:

0(默认,与特定的家族相关的协议,若是0系统会根据地址格式和套接类别自动选择一个合适的协议);

 

sock.setblocking(bool)   #(是否blocking,默认为True,如果设置Falseacceptrecv时一旦无数据则会报错)

 

sock.setsockopt(level,option,value)   #(设置套接字选项,level是被设置的选项的级别,若要想在套接字上设置level必须为SOL_SOCKET,在此级别下option有众多选项其中SO_REUSEADDR表示打开或关闭地址利用功能,value0表示关闭,非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中的selectpollepoll都是IO多路复用的机制):

select(通过select()系统调用来监视多个文件描述符的数组,当select返回后,该数组中就绪的文件描述符便会被内核修改标志位,使得进程可以获得这些文件描述符从而进行后续的读写操作;此策略的缺点,单个进程能够监视的文件描述符的数量存在最大限制,Linux默认为1024,随着文件描述符数量的增大,其复制的开销也线性增长);

poll(与select类似,但没有文件描述符的限制);

epoll(内核直接支持,基于事件驱动event-driven(分两部分:注册事件和触发事件);

 

Python中有select模块,该模块提供了selectpollepoll这三种方法)

 

rs,ws,xs=select.select(rlist,wlist,xlist[,timeout])   #select方法用来监视文件句柄,如果句柄发生变化,则获取该句柄;括号中前三个参数必须,返回三个列表)

rlist中的句柄发生可读时(acceptread),则获取发生变化的句柄并添加到rs中;

wlist中含有句柄时,则将该序列中所有的句柄添加到ws中;

xlist中的句柄发生错误时,则将该发生错误的句柄添加到xs中;

timeout未设置select会一直blocking,直到监听的句柄发生变化;当timeout1时,如果监听的句柄无任何变化则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_INETipv4地址,AF_INET6ipv6地址,AF_UNIX只能用于单一的Unix系统连接;参数二类型:SOCK_STREAMtcp协议默认,SOCK_DGRAMudp

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-sideclient-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-sideclient-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-sideclient均可使用)

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用,flagfalse则是non-blockingflagTrue则是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-sideclient-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.pyclient_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.pyclient_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



本文转自 chaijowin 51CTO博客,原文链接:http://blog.51cto.com/jowin/1834189,如需转载请自行联系原作者

相关文章:

  • zookeeper系列(七)实战分布式命名服务
  • Animations的使用
  • 利用Python生成随机4位验证码
  • 测试标准学习
  • 一些不常见的css知识
  • 第四课——MFC应用程序框架
  • 列表、元祖概述
  • 拨云见日—深入解析Oracle TX 行锁(上)
  • 询问Spring Bott和高并发框架两个问题
  • 用 vue 组件自定义 v-model, 实现一个 Tab 组件。
  • MicroProfile 1.2新增功能介绍
  • Google瓦片地图算法解析
  • TransactionScope只要一个操作失败,它会自动回滚,Complete表示事务完成
  • 网络流媒体技术及其应用
  • 【安全牛学习笔记】w3af-截断代理
  • 【108天】Java——《Head First Java》笔记(第1-4章)
  • 【划重点】MySQL技术内幕:InnoDB存储引擎
  • 【剑指offer】让抽象问题具体化
  • 4月23日世界读书日 网络营销论坛推荐《正在爆发的营销革命》
  • CSS3 变换
  • CSS实用技巧
  • gitlab-ci配置详解(一)
  • go语言学习初探(一)
  • HTTP 简介
  • iOS小技巧之UIImagePickerController实现头像选择
  • Linux各目录及每个目录的详细介绍
  • Web标准制定过程
  • 程序员最讨厌的9句话,你可有补充?
  • 飞驰在Mesos的涡轮引擎上
  • 警报:线上事故之CountDownLatch的威力
  • 前端之React实战:创建跨平台的项目架构
  • 深入浅出webpack学习(1)--核心概念
  • 吐槽Javascript系列二:数组中的splice和slice方法
  • 小程序 setData 学问多
  • 小程序01:wepy框架整合iview webapp UI
  • 一起参Ember.js讨论、问答社区。
  • 用jQuery怎么做到前后端分离
  • ​DB-Engines 12月数据库排名: PostgreSQL有望获得「2020年度数据库」荣誉?
  • #pragma预处理命令
  • #常见电池型号介绍 常见电池尺寸是多少【详解】
  • #我与Java虚拟机的故事#连载16:打开Java世界大门的钥匙
  • (C++)栈的链式存储结构(出栈、入栈、判空、遍历、销毁)(数据结构与算法)
  • (C语言)深入理解指针2之野指针与传值与传址与assert断言
  • (非本人原创)史记·柴静列传(r4笔记第65天)
  • (附源码)ssm高校实验室 毕业设计 800008
  • (三维重建学习)已有位姿放入colmap和3D Gaussian Splatting训练
  • (轉貼) 寄發紅帖基本原則(教育部禮儀司頒布) (雜項)
  • .net 无限分类
  • .NET/ASP.NETMVC 大型站点架构设计—迁移Model元数据设置项(自定义元数据提供程序)...
  • .NET关于 跳过SSL中遇到的问题
  • [ 云计算 | AWS 实践 ] 基于 Amazon S3 协议搭建个人云存储服务
  • []串口通信 零星笔记
  • [BZOJ 1032][JSOI2007]祖码Zuma(区间Dp)
  • [GXYCTF2019]禁止套娃
  • [java面试]宇信易诚 广州分公司 java笔试题目回忆录