TCP Client
- Client Programming Steps:
- Creating a Socket Object
- IP and Port,connect () methods connected to the server
- Transferring data
- Send and receive data using the Send, Recv method
- Close the connection and release the resource
The simplest client:
#TCP Client clients Import socketclient = Socket.socket () client.connect ((' 127.0.0.1 ', 9999)) Client.send ("Hi, I ' m client1.") Encode ()) Client.close () #运行
Service-Side status:
[16:08:25] [showthreads,1796] [<_mainthread (Mainthread, started 9816), <thread (show_client, started daemon 9344), <thread (Accept, started daemon 5908), <thread (Showthreads, started 1796) >][16:08:26] [Accept, 5908] <socket.socket fd=424, family=addressfamily.af_inet, Type=socketkind.sock_stream, proto=0, Laddr= (' 127.0.0.1 ', 9999), raddr= (' 127.0.0.1 ', 5287) >-(' 127.0.0.1 ', 5287) [16:08:26] [show_client,9344] {(' 127.0.0.1 ', 5287 ): <_io. Textiowrapper mode= ' rw ' encoding= ' UTF8 ' >}2017/12/24 16:08:26 127.0.0.1:5287hi, I ' m client1. [16:08:26] [recv,980] 2017/12/24 16:08:26 127.0.0.1:5287hi, I ' m client1. [16:08:26] [recv,980] (' 127.0.0.1 ', 5287) quit[16:08:28] [showthreads,1796] [<_mainthread (Mainthread, started 9816) , <thread (show_client, started daemon 9344), <thread (Accept, started daemon 5908);, <thread ( Showthreads, started 1796);]
Encapsulate the TCP client above into a class:
1) sticked
#TCP client clients encapsulated into class import Socketclass chatclient: def __init__ (self): pass def start: Pass def _recv (self): Pass def Send (self): pass def Stop (self): Pass
2) Basic functions
Client:
#TCP client clients are encapsulated into class import socket,threading,logging,datetimedatefmt= "%h:%m:%s" FORMAT = "[% (asctime) s]\t [% (threadname ) s,% (thread) d]% (message) S "Logging.basicconfig (LEVEL=LOGGING.INFO,FORMAT=FORMAT,DATEFMT=DATEFMT) class ChatClient : Def __init__ (self,ip= ' 127.0.0.1 ', port=9999): Self.sock = Socket.socket () self.addr = (Ip,port) s Elf.event = Threading. Event () Self.start () def start (self): Self.sock.connect (SELF.ADDR) # Ready to receive data, Recv is blocked, starting a new thread Threading. Thread (target=self._recv,name= ' recv '). Start () def _recv (self): And not Self.event.is_set (): Try: data = SELF.SOCK.RECV (1024x768) #阻塞 except Exception as E:logging.info (e) #有任何异常保证退出 Break msg = "{:%h:%m:%s} {}:{}\n{}\n". Format (Datetime.datetime.now (), *self.addr,data.decode (). Str IP ()) # Print (Type (msg), msg) Logging.info ("{}". Format (Data.decode ())) def send (SELF,MSG:STR): DatA = "{}\n". Format (Msg.strip ()). Encode () self.sock.send (data) def stop (self): Logging.info (' {} broken '. For Mat (SELF.ADDR)) Self.sock.close () self.event.wait (3) Self.event.set () logging.info ("Byebye") de F Main (): E = Threading. Event () cc = ChatClient () while true:msg = input (">>>") if msg.strip () = = ' Quit ': Cc.stop () Break Cc.send (msg) If __name__ = = ' __main__ ': Main ()
Service side:
#TCP Server converted to Makefileimport threading,logging,time,random,datetime,socketdatefmt= "%h:%m:%s" FORMAT = "[% (Asctime) S ]\t [% (threadname) s,% (thread) d]% (message) S "Logging.basicconfig (level=logging.info,format=format,datefmt=datefmt ) class Chatserver:def __init__ (self,ip= ' 127.0.0.1 ', port=9999): #启动服务 self.addr = (ip,port) Self.sock = s Ocket.socket () Self.event = Threading. Event () self.clients = {} #客户端 def show_client (self): When not Self.event.is_set (): If Len (SE lf.clients) > 0:logging.info (self.clients) self.event.wait (3) def start (self): Self.sock.bind (SELF.ADDR) Self.sock.listen () # Accept will block the main thread, so open a new threading threading. Thread (target=self._accept,name= ' accept ', daemon=true). Start () threading. Thread (target=self.show_client,name= ' show_client ', daemon=true). Start () def stop (self): for C in Self.clients.val UEs (): C.close () Self.sock.close ()Self.event.wait (3) self.event.set () def _accept (self): And not Self.event.is_set (): #多人连接 Co Nn,client = self.sock.accept () #阻塞 f = conn.makefile (mode= ' RW ') self.clients[client] = f Logging.info ("{}-{}". Format (conn,client)) # recv is blocked by default, and each connection is separated by a recv thread ready to receive data threading. Thread (TARGET=SELF._RECV, args= (f, client), name= ' recv ', daemon=true). Start () def _recv (self, F, client): #接收客户端数据 While not Self.event.is_set (): Try:data = F.readline () except Exception: data = ' quit ' finally:msg = Data.strip () # Client notification exit mechanism if msg = = ' quit ': F.close () self.clients.pop (client) Logging.info (' { } quit '. Format (client) Break msg = "{:%y/%m/%d%h:%m:%s} {}:{}\n{}\n". Format (datetime.datet Ime.now (), *client,data) # msg = data print (msg) logging.info (msg) for C in Self.clients.values (): # Print (Type (msg)) C.writelines (msg) C.flush () cs = Chatserver () print ('!!!!!!!!!!! ') Cs.start () print (' ~~~~~~~~~~~~~~~~~~~~ ') e = threading. Event () def showthreads (e:threading. Event): While not e.wait (3): Logging.info (Threading.enumerate ()) threading. Thread (target=showthreads,name= ' showthreads ', args= (E,)). Start () and not e.wait (1): # Sever console exit Mode cmd = input (' >& Gt;> '). Strip () if cmd = = ' Quit ': Cs.stop () e.wait (3) break
Operation Result:
#服务端 ~~~~~~~~~~~~~~~~~~~~>>> [17:26:14] [show_client,7824] {(' 127.0.0.1 ', 7517): <_io. Textiowrapper mode= ' rw ' encoding= ' cp936 ' >}[17:26:14] [accept,3832] <socket.socket fd=400, family= Addressfamily.af_inet, Type=socketkind.sock_stream, proto=0, laddr= (' 127.0.0.1 ', 9999), raddr= (' 127.0.0.1 ', 7517) >-(' 127.0.0.1 ', 7517) [17:26:15] [showthreads,5928] [<thread (Accept, started daemon 3832), <thread (Show_ Client, started daemon 7824), <thread (recv, started daemon 2112), <_mainthread (Mainthread, started 7412) & gt;, <thread (Showthreads, started 5928) >][17:26:17] [show_client,7824] {(' 127.0.0.1 ', 7517): <_io. Textiowrapper mode= ' rw ' encoding= ' cp936 ' >}[17:26:18] [showthreads,5928] [<thread (Accept, started daemon 3832) , <thread (show_client, started daemon 7824), <thread (recv, started daemon 2112);, <_mainthread ( Mainthread, started 7412), <thread (Showthreads, started 5928) >][17:26:19] [recv,2112] 2017/12/24 17:26:19 127.0.0.1:7517HELLO12017/12/24 17:26:19 127.0.0.1:7517hello1[17:26:20] [show_client,7824] {(' 127.0.0.1 ', 7517): < _io. Textiowrapper mode= ' rw ' encoding= ' cp936 ' >}[17:26:21] [showthreads,5928] [<thread (Accept, started daemon 3832) , <thread (show_client, started daemon 7824), <thread (recv, started daemon 2112);, <_mainthread ( Mainthread, started 7412), <thread (Showthreads, started 5928) >][17:26:23] [show_client,7824] {(' 127.0.0.1 ', 7517): <_io. Textiowrapper mode= ' rw ' encoding= ' cp936 ' >}[17:26:23] [accept,3832] <socket.socket fd=436, family= Addressfamily.af_inet, Type=socketkind.sock_stream, proto=0, laddr= (' 127.0.0.1 ', 9999), raddr= (' 127.0.0.1 ', 7539) >-(' 127.0.0.1 ', 7539) [17:26:24] [showthreads,5928] [<thread (show_client, started daemon 7824);, <thread ( Recv, started daemon 2112), <_mainthread (Mainthread, started 7412), <thread (Accept, started daemon 3832) & gt;, <thread (recv, started daemon 6748);, <thread (showthReads, started 5928) >]2017/12/24 17:26:25 127.0.0.1:7539[17:26:25] [recv,6748] 2017/12/24 17:26:25 127.0.0.1:7539HELLO2HELLO2[17:26:26] [show_client,7824] {(' 127.0.0.1 ', 7517): <_io. Textiowrapper mode= ' rw ' encoding= ' cp936 ';, (' 127.0.0.1 ', 7539): <_io. Textiowrapper mode= ' rw ' encoding= ' cp936 ' >}[17:26:27] [showthreads,5928] [<thread (show_client, started daemon 7824), <thread (recv, started daemon 2112), <_mainthread (Mainthread, started 7412);, <thread (Accept , started daemon 3832), <thread (recv, started daemon 6748), <thread (Showthreads, started 5928) >][ 17:26:29] [show_client,7824] {(' 127.0.0.1 ', 7517): <_io. Textiowrapper mode= ' rw ' encoding= ' cp936 ';, (' 127.0.0.1 ', 7539): <_io. Textiowrapper mode= ' rw ' encoding= ' cp936 ' >}[17:26:30] [showthreads,5928] [<thread (show_client, started daemon 7824), <thread (recv, started daemon 2112), <_mainthread (Mainthread, started 7412);, <thread (Accept , started daemon 3832) >, <thread (recv, started daemon 6748), <thread (Showthreads, started 5928) >][17:26:32] [show_client,7824 ] {(' 127.0.0.1 ', 7517): <_io. Textiowrapper mode= ' rw ' encoding= ' cp936 ';, (' 127.0.0.1 ', 7539): <_io. Textiowrapper mode= ' rw ' encoding= ' cp936 ' >}[17:26:33] [showthreads,5928] [<thread (show_client, started daemon 7824), <thread (recv, started daemon 2112), <_mainthread (Mainthread, started 7412);, <thread (Accept , started daemon 3832), <thread (recv, started daemon 6748), <thread (Showthreads, started 5928) >][ 17:26:35] [show_client,7824] {(' 127.0.0.1 ', 7517): <_io. Textiowrapper mode= ' rw ' encoding= ' cp936 ';, (' 127.0.0.1 ', 7539): <_io. Textiowrapper mode= ' rw ' encoding= ' cp936 ' >}[17:26:36] [showthreads,5928] [<thread (show_client, started daemon 7824), <thread (recv, started daemon 2112), <_mainthread (Mainthread, started 7412);, <thread (Accept , started daemon 3832), <thread (recv, started daemon 6748), <thread (Showthreads, started 5928);]
#客户端1 >>> hello1[17:26:19] [recv,2604] 2017/12/24 17:26:19 127.0.0.1:7517hello1>>> [17:26:25] [recv, 2604] 2017/12/24 17:26:25 127.0.0.1:7539hello2[17:26:37] [recv,2604] [Winerror 10054] The remote host forced the shutdown of an existing connection.
#客户端2 >>> hello2>>> [17:26:25] [recv,4044] 2017/12/24 17:26:25 127.0.0.1:7539hello2[17:26:37] [recv, 4044] [Winerror 10054] The remote host forced the shutdown of an existing connection.
In the above example on the client side, if the server is actively disconnected, the client needs exception handling.
[Python Network Programming] TCP Client (iv)