Python_Socket 柔光的暖阳◎ 2022-02-03 08:51 209阅读 0赞 socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求。 socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,对于文件用【打开】【读写】【关闭】模式来操作。socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭) socket和file的区别: * file模块是针对某个指定文件进行【打开】【读写】【关闭】 * socket模块是针对 服务器端 和 客户端Socket 进行【打开】【读写】【关闭】 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNzk0MjY2_size_16_color_FFFFFF_t_70][] socket server _data_ = '2019/5/9 9:06' _author = 'XiaoYang' import socket ip_port = ('127.0.0.1',9999) # 定义socket类型 sk = socket.socket() # 绑定本机address ip sk.bind(ip_port) # 监听线程 sk.listen(5) while True: #循环接收 print ('server waiting...') # 接收信息 conn, addr = sk.accept() client_info = conn.recv(1024) print(client_info.decode("utf-8")) conn.sendall('大声点,听不见'.encode("utf-8")) conn.close() socket client _data_ = '2019/5/9 9:18' _author = 'XiaoYang' import socket ip_port = ('127.0.0.1',9999) sk = socket.socket() sk.connect(ip_port) sk.sendall('你好'.encode("utf-8")) server_reply = sk.recv(1024) print (server_reply.decode("utf-8")) sk.close() **功能** **sk = socket.socket(socket.AF\_INET,socket.SOCK\_STREAM,0)** 参数一:地址簇 socket.AF_INET IPv4(默认) socket.AF_INET6 IPv6 socket.AF_UNIX 只能够用于单一的Unix系统进程间通信 参数二:类型 socket.SOCK_STREAM 流式socket , for TCP (默认) socket.SOCK_DGRAM 数据报式socket , for UDP socket.SOCK_RAW 原始套接字,普通的套接字无法处理ICMP、IGMP等网络报文,而SOCK_RAW可以;其次,SOCK_RAW也可以处理特殊的IPv4报文;此外,利用原始套接字,可以通过IP_HDRINCL套接字选项由用户构造IP头。 socket.SOCK_RDM 是一种可靠的UDP形式,即保证交付数据报但不保证顺序。SOCK_RAM用来提供对原始协议的低级访问,在需要执行某些特殊操作时使用,如发送ICMP报文。SOCK_RAM通常仅限于高级用户或管理员运行的程序使用。 socket.SOCK_SEQPACKET 可靠的连续数据包服务 参数三:协议 0 (默认)与特定的地址家族相关的协议,如果是 0 ,则系统就会根据地址格式和套接类别,自动选择一个合适的协议 **sk.bind(address)** s.bind(address) 将套接字绑定到地址。address地址的格式取决于地址族。在AF\_INET下,以元组(host,port)的形式表示地址。 **sk.listen(backlog)** 开始监听传入连接。backlog指定在拒绝连接之前,可以挂起的最大连接数量。 backlog等于5,表示内核已经接到了连接请求,但服务器还没有调用accept进行处理的连接个数最大为5 这个值不能无限大,因为要在内核中维护连接队列 **sk.setblocking(bool)** 是否阻塞(默认True),如果设置False,那么accept和recv时一旦无数据,则报错。 **sk.accept()** 接受连接并返回(conn,address),其中conn是新的套接字对象,可以用来接收和发送数据。address是连接客户端的地址。 接收TCP 客户的连接(阻塞式)等待连接的到来 **sk.connect(address)** 连接到address处的套接字。一般,address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。 **sk.connect\_ex(address)** 同上,只不过会有返回值,连接成功时返回 0 ,连接失败时候返回编码,例如:10061 **sk.close()** 关闭套接字 **sk.recv(bufsize\[,flag\])** 接受套接字的数据。数据以字符串形式返回,bufsize指定**最多**可以接收的数量。flag提供有关消息的其他信息,通常可以忽略。 **sk.recvfrom(bufsize\[.flag\])** 与recv()类似,但返回值是(data,address)。其中data是包含接收数据的字符串,address是发送数据的套接字地址。 **sk.send(string\[,flag\])** 将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。即:可能未将指定内容全部发送。 **sk.sendall(string\[,flag\])** 将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。 内部通过递归调用send,将所有内容发送出去。 **sk.sendto(string\[,flag\],address)** 将数据发送到套接字,address是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。该函数主要用于UDP协议。 **sk.settimeout(timeout)** 设置套接字操作的超时期,timeout是一个浮点数,单位是秒。值为None表示没有超时期。一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作(如 client 连接最多等待5s ) **sk.getpeername()** 返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)。 **sk.getsockname()** 返回套接字自己的地址。通常是一个元组(ipaddr,port) **sk.fileno()** 套接字的文件描述符 实例教程 server _data_ = '2019/5/9 11:37' _author = 'XiaoYang' import socket ip_address = ("127.0.0.1",8005) sk = socket.socket() sk.bind(ip_address) sk.listen(5) while True: conn,address = sk.accept() conn.sendall('欢迎致电 10086,请输入1xxx,0转人工服务.'.encode()) Flag = True while Flag: data = conn.recv(1024).decode() if data == 'exit': Flag = False elif data == '0': conn.sendall('通过可能会被录音.balabala一大推'.encode()) else: conn.sendall('请重新输入.'.encode()) conn.close() client _data_ = '2019/5/9 11:20' _author = 'XiaoYang' import socket ip_port = ('127.0.0.1',8005) sk = socket.socket() sk.connect(ip_port) sk.settimeout(5) while True: data = sk.recv(1024).decode() print ('receive:',data) inp = input('please input:') sk.sendall(inp.encode()) if inp == 'exit': break sk.close() **SocketServer** The [`socketserver`][socketserver] module simplifies the task of writing network servers. SocketServer模块简化了写入网络服务器的任务。 There are four basic concrete server classes: 有四个基本的具体服务器类: ***class *`socketserver.``TCPServer`(*server\_address*, *RequestHandlerClass*, *bind\_and\_activate=True*)** This uses the Internet TCP protocol, which provides for continuous streams of data between the client and server. If *bind\_and\_activate* is true, the constructor automatically attempts to invoke [`server_bind()`][server_bind] and[`server_activate()`][server_activate]. The other parameters are passed to the [`BaseServer`][BaseServer] base class. 这将使用InternetTCP协议,该协议提供客户机和服务器之间的连续数据流。如果bind\_and\_activate为true,则构造函数将自动尝试调用server\_bind()和server\_activate()。其他参数将传递给baseserver基类。 ***class *`socketserver.``UDPServer`(*server\_address*, *RequestHandlerClass*, *bind\_and\_activate=True*)** This uses datagrams, which are discrete packets of information that may arrive out of order or be lost while in transit. The parameters are the same as for [`TCPServer`][TCPServer]. 它使用数据报,数据报是离散的信息包,在传输过程中可能现无序到达或丢失。参数与tcpserver相同。 ***class *`socketserver.``UnixStreamServer`(*server\_address*, *RequestHandlerClass*, *bind\_and\_activate=True*)** ***class *`socketserver.``UnixDatagramServer`(*server\_address*, *RequestHandlerClass*,*bind\_and\_activate=True*)** These more infrequently used classes are similar to the TCP and UDP classes, but use Unix domain sockets; they’re not available on non-Unix platforms. The parameters are the same as for [`TCPServer`][TCPServer]. These four classes process requests *synchronously*; each request must be completed before the next request can be started. This isn’t suitable if each request takes a long time to complete, because it requires a lot of computation, or because it returns a lot of data which the client is slow to process. The solution is to create a separate process or thread to handle each request; the [`ForkingMixIn`][ForkingMixIn] and [`ThreadingMixIn`][ThreadingMixIn] mix-in classes can be used to support asynchronous behaviour. 这些更不常用的类类似于TCP和UDP类,但使用Unix域套接字;它们在非Unix平台上不可用。参数与tcpserver相同。 这四个类同步处理请求;每个请求必须在下一个请求启动之前完成。如果每个请求需要很长时间才能完成,这是不合适的,因为它需要大量的计算,或者因为它返回大量的数据,而客户机处理这些数据很慢。解决方案是创建一个单独的进程或线程来处理每个请求;类中的forkingmixin和threadingmixin混合可用于支持异步行为。 **There are five classes in an inheritance diagram, four of which represent synchronous servers of four types:** ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNzk0MjY2_size_16_color_FFFFFF_t_70 1][] Note that [`UnixDatagramServer`][UnixDatagramServer] derives from [`UDPServer`][UDPServer], not from [`UnixStreamServer`][UnixStreamServer] — the only difference between an IP and a Unix stream server is the address family, which is simply repeated in both Unix server classes. ***class *`socketserver.``ForkingMixIn`** ***class *`socketserver.``ThreadingMixIn`** Forking and threading versions of each type of server can be created using these mix-in classes. For instance, [`ThreadingUDPServer`][ThreadingUDPServer] is created as follows: class ThreadingUDPServer(ThreadingMixIn, UDPServer): pass The mix-in class comes first, since it overrides a method defined in [`UDPServer`][UDPServer]. Setting the various attributes also changes the behavior of the underlying server mechanism. ***class *`socketserver.``ForkingTCPServer`** ***class *`socketserver.``ForkingUDPServer`** ***class *`socketserver.``ThreadingTCPServer`** ***class *`socketserver.``ThreadingUDPServer`** 这些类是使用混合类预先定义的。 **Request Handler Objects** ***class *`socketserver.``BaseRequestHandler`** This is the superclass of all request handler objects. It defines the interface, given below. A concrete request handler subclass must define a new [`handle()`][handle] method, and can override any of the other methods. A new instance of the subclass is created for each request. 这是所有请求处理程序对象的超类。它定义了下面给出的接口。具体的请求处理程序子类必须定义一个新的handle()方法,并且可以重写任何其他方法。为每个请求创建子类的新实例。 **`setup`()** Called before the [`handle()`][handle] method to perform any initialization actions required. The default implementation does nothing. **`handle`()** This function must do all the work required to service a request. The default implementation does nothing. Several instance attributes are available to it; the request is available as `self.request`; the client address as `self.client_address`; and the server instance as `self.server`, in case it needs access to per-server information. The type of `self.request` is different for datagram or stream services. For stream services,`self.request` is a socket object; for datagram services, `self.request` is a pair of string and socket. 此函数必须完成服务请求所需的所有工作。默认实现什么也不做。它有几个实例属性可用;请求可用作self.request;客户机地址可用作self.client\_地址;服务器实例可用作self.server,以防需要访问每个服务器的信息。 对于数据报或流服务,self.request的类型不同。对于流服务,self.request是一个套接字对象;对于数据报服务,self.request是一对字符串和套接字。 **`finish`()** Called after the [`handle()`][handle] method to perform any clean-up actions required. The default implementation does nothing. If [`setup()`][setup] raises an exception, this function will not be called. 在handle()方法之后调用,以执行所需的任何清理操作。默认实现什么也不做。如果setup()引发异常,则不会调用此函数。 -------------------- [`socketserver.TCPServer`][TCPServer] Example _data_ = '2019/5/12 19:14' _author = 'XiaoYang' import socketserver class MyTCPHandler(socketserver.BaseRequestHandler): def handle(self): # self.request is the TCP socket connected to the client self.data = self.request.recv(1024).strip() print("{} wrote:".format(self.client_address[0])) print(self.data) # just send back the same data, but upper-cased self.request.sendall(self.data.upper()) if __name__ == "__main__": HOST, PORT = "localhost", 9999 # Create the server, binding to localhost on port 9999 server = socketserver.TCPServer((HOST, PORT), MyTCPHandler) # Activate the server; this will keep running until you # interrupt the program with Ctrl-C server.serve_forever() client _data_ = '2019/5/12 19:24' _author = 'XiaoYang' import socket HOST, PORT = "localhost", 9999 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 链接socketserver sock.connect((HOST, PORT)) try: sock.send("你好".encode()) # Receive data from the server and shut down received = str(sock.recv(1024), "utf-8") print("recive %s" %received) finally: sock.close() 以上server服务只支持单线程,不能实现多并发,哈哈,在server端做一下更改就可以了 把 <table> <tbody> <tr> <td> <p>1</p> </td> <td> <p><code>server </code><code>=</code> <code>socketserver.TCPServer((HOST, PORT), MyTCPHandler)</code></p> </td> </tr> </tbody> </table> 改成 <table> <tbody> <tr> <td> <p>1</p> </td> <td> <p><code>server </code><code>=</code> <code>socketserver.ThreadingTCPServer((HOST, PORT), MyTCPHandler)</code></p> </td> </tr> </tbody> </table> [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNzk0MjY2_size_16_color_FFFFFF_t_70]: /images/20220203/7bede0eb649e4b9983c0a38ca6c31bc7.png [socketserver]: https://docs.python.org/3.5/library/socketserver.html#module-socketserver [server_bind]: https://docs.python.org/3.5/library/socketserver.html#socketserver.BaseServer.server_bind [server_activate]: https://docs.python.org/3.5/library/socketserver.html#socketserver.BaseServer.server_activate [BaseServer]: https://docs.python.org/3.5/library/socketserver.html#socketserver.BaseServer [TCPServer]: https://docs.python.org/3.5/library/socketserver.html#socketserver.TCPServer [ForkingMixIn]: https://docs.python.org/3.5/library/socketserver.html#socketserver.ForkingMixIn [ThreadingMixIn]: https://docs.python.org/3.5/library/socketserver.html#socketserver.ThreadingMixIn [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNzk0MjY2_size_16_color_FFFFFF_t_70 1]: /images/20220203/14e066ec89cc488ab55925bb52e09a8c.png [UnixDatagramServer]: https://docs.python.org/3.5/library/socketserver.html#socketserver.UnixDatagramServer [UDPServer]: https://docs.python.org/3.5/library/socketserver.html#socketserver.UDPServer [UnixStreamServer]: https://docs.python.org/3.5/library/socketserver.html#socketserver.UnixStreamServer [ThreadingUDPServer]: https://docs.python.org/3.5/library/socketserver.html#socketserver.ThreadingUDPServer [handle]: https://docs.python.org/3.5/library/socketserver.html#socketserver.BaseRequestHandler.handle [setup]: https://docs.python.org/3.5/library/socketserver.html#socketserver.BaseRequestHandler.setup
相关 网络通信挑战:Pythonsocket和HTTP请求 在网络通信中,Python的socket库和HTTP请求是非常常见的工具。下面分别介绍这两种方式在应对网络通信挑战时的应用。 1. **Python Socket通信**: 向右看齐/ 2025年02月01日 11:18/ 0 赞/ 31 阅读
还没有评论,来说两句吧...