• python-网络编程-socket编程


    一、TCPIP(网络通信协议)简介

          TCP:(Transmission Control Protocol)传输控制协议,面向有连接的通信协议

       UDP:数据报文协议,面向无连接的通信协议

           IP:(Internet Protocol)网际协议

          

    二、socket语法

          网络七层模型(OSI模型)

          1物理层——>2数据链路层(mac地址)——>3网络层(IP)——>4传输层(TCP/IP 、UDP协议传输)——>5会话层——>6表示层——>7应用层(http、ftp、smtp、pop3)

          socket语法及相关知识点:

            socket是为两个程序之间建立一个双向通道,来实现数据传输。  网络通信是通过ip+port来定位具体的目标机器的具体的服务,操作系统有0-65535个端口,每个端口独立对外提供服务。   

               建立一个socket必须有两个端:服务端和客户端

               服务端:被动等待接受客户端的请求

                          建立流程:1.建立一个socket实例sk——>sk.bind()设置服务端可监听的网络地址和端口号——>sk.listen()开始监听——>

                                           cnn,val=sk.accepr()接受客户端的连接——>cnn.recv()接受数据——>cnn.send()发送数据——>close

                  1、建立一个socket实例 :socket.socket()

    1 import socket
    2 server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

                    第一个参数为:地址簇

                    socket.AF_INET       ipv4

                    socket.AF_INET6     IPV6           

                    socket.AF_UNIX       unix本机进行之间通信    

           

                   第二个参数:socket类型

                    socket.SOCKET_STREAM   for tcp

                    socket.SOCKET_DGRAM    for udp         

          socket.SOCK_RAW   原始套接字,普通的套接字无法处理ICMP、IGMP等网络报文,而SOCK_RAW可以;其次,SOCK_RAW也可以处理特殊的IPv4报文;此外,利用原始套接字,可以通过IP_HDRINCL套接字选项由用户构造IP头。

            socket.SOCK_RDM       是一种可靠的UDP形式,即保证交付数据报但不保证顺序。SOCK_RAM用来提供对原始协议的低级访问,在需要执行某些特殊操作时使用,如发送ICMP报文。SOCK_RAM通常仅限于高级用户或管理员运行的程序使用。

                    2、 绑定地址:sk.bind(address)

                         address的格式取决于地址簇,如果是IPV4,则以元祖的形式传入地址

    1 server.bind(('0.0.0.0',8001))

                3、开始监听:sk.listen(backlog)

                        开始监听传入的连接,backlog表示在拒绝连接之前,可挂起的最大连接数,backlog最大为5

    1 server.listen(5)

                4、接收连接并返回新套接字对象和客户端地址

    1 cnn,client_addr=server.accept()

                  cnn为新的套接字对象,clinet为连接的客户端地址

                5、接受和发送客户端数据

    1 cnn.recv(1024)
    2 cnn.send(b'got your msg')

              客户端:主动向服务端发送请求

                         流程:建立一个socket实例c——>c.connect()连接服务端——>c.send()发送数据——>c.recv()接受数据——>c.close()           

    1 import socket
    2 client=socket.socket()     #  1、建立socket实例
    3 client.connect(('localhost',8001))   #2、连接
    4 msg=input('>>:')
    5 client.send(msg.encode())       #3、发送数据
    6 print('send:%s' %msg)
    7 data=client.recv(1024)
    8 print('receive from server:%s'%data)     #4、接受数据

              下面是小练习:

                服务端:

     1 import socket
     2 server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
     3 server.bind(('127.168.0.1',8001))
     4 server.listen(5)
     5 print('------------start to listen--------')
     6 while True:    #客户端断开与服务端的连接时,防止直接跳出第二个循环后,报错,而是回到该循环,重新接受其他客户端的请求
     7     cnn,client_addr=server.accept()
     8     print(cnn,client_addr)
     9     while True:
    10         try:
    11             data=cnn.recv(1024)    #有一个客户端断开连接是,recv不到连接,会报错,用try来进行异常处理,防止程序终止
    12             print('客户端:%s'%data)
    13             s_data=input('服务端:')
    14             cnn.send(s_data.encode())
    15         except ConnectionResetError as e:
    16             print(e)
    17             break

                 客户端:

     1 import socket
     2 client=socket.socket()
     3 client.connect(('127.168.0.1',8001))
     4 
     5 while True:
     6     msg=input('客户端:')
     7     client.send(msg.encode())
     8     # print('send:%s' %msg)
     9     data=client.recv(1024)
    10     print('服务端:%s'%data)

     三、SocketServer网络服务器框架

           ScoketServer可实现多线程的网络服务,它包括5个服务类

           BaseServer:不直接对外服务,是一下四个服务类的基类

           TCPServer:处理tcp协议的网络传输

                  UDPServer:处理udp协议的网络传输

                  UnixStreamServer:继承TCPserver,用于unix平台,实现进程间的通信

                  UnixDatagramServer:继承UDPServer,用于unix平台,实现进程间的通信

           一、创建一个tcp协议的socketserver

                1、首先定义一个类,继承socketserver.BaseRequestHandler,重写该类中的handle方法

                     handle方法封装的是服务端和客户端的交互体           

     1 import socketserver
     2 class MYTCPHander(socketserver.BaseRequestHandler):
     3     def handle(self):   #封装服务端和客户端的交互体,即accept之后的内容:recv send这些,不包括listen
     4         while True:
     5             try:
     6                 self.data=self.request.recv(1024).strip()    #self.request:套接字   即cnn,client_addr=server.accept()中的cnn
     7 # print(self.client_address) # 打印客户端的IP和端口号  8 print(self.data.decode())  9 self.request.send(b'got your msg') 10 except Exception as e: 11 print(e)

                 2、创建一个server实例

                     绑定服务的地址和端口号,创建一个TCPServer实例,并开始监听和处理客户端的请求

    1 if __name__=='__main__':
    2     HOST,PORT='0.0.0.0',9999
    3     server=socketserver.TCPServer((HOST,PORT),MYTCPHander)     #创建一个tap类型的socketserver实例,每连接一个客户端就会生成一个实例(注意不是说每次客户端发送数据)
    4     server.serve_forever()      #开始监听,开始处理客户端的请求request

               以上的脚本还是一个单线程的,如何实现多线程网络通信呢?只需要在创建socketserver实例的时候,讲socketserver.TCPServer改为socketserver.ThreadingTCPServer即可 

    1 if __name__=='__main__':
    2     HOST,PORT='0.0.0.0',9999
    3     server=socketserver.ThreadingTCPServer((HOST,PORT),MYTCPHandler)
    4     print('__________________start to listen___________________')
    5     server.serve_forever()

                 使用ThreadingTCPServer后,每次进来一个连接就会生成一个线程

  • 相关阅读:
    UISearchBar的常用代理
    iOS 上传图片压缩大小设置
    __weak typeof(self)weakSelf = self;的解释和使用
    运动事件(MotionEvent)
    iOS 获取当前window
    保留小数
    ios 转图片
    iOS提示弹窗
    iOS 获取ip地址
    微信小程序 watch监听数据变化 类似vue中的watch
  • 原文地址:https://www.cnblogs.com/songxiaonan/p/6110124.html
Copyright © 2020-2023  润新知