当前位置:首页 > Python教程 > python技巧

Python 3学习 ——网络编程

Python 学习——面向对象

 写此博客 是为了激励自己,并且将自己的心得以及遇到的问题与人分享

一、网络编程

  SOCK_STRAM :TCP  SOCK_Dgram :UDP  两个参数决定了不同的连接方式,主要使用TCP连接。

family = AF_INET  :服务器之间的通信  family = AF_UNIX :Unix 不同进程的通信。

  send 或者 sendall 方法传送的类型一定要是 bytes 类型。

 

(相互通信)小应用:server 端 和 client 端进行通信。

  server 端代码:

技术分享图片 技术分享图片
                 1
                #
                author:"LFD"
                 2
                #
                date: 2018/5/14
                 3
                 4
                import
                 socket

                 5
                 6 sk = socket.socket() #什么都不加就可以了,参数已经默认写好了 7print(sk)   #<socket.socket fd=428, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0> 8 9 address = (127.0.0.1,8000) #回环地址,代表了默认的IP地址就是当前这台电脑的IP地址。 8000是端口号。1011 sk.bind(address) # 绑定了IP地址和端口1213 sk.listen(3)  # 决定着serve端到底可以容纳多少个排队人数。14print(我在等待连接)
15 con,addr = sk.accept()
16print(con) #(<socket.socket fd=504, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM,17#proto=0, laddr=(‘127.0.0.1‘, 8000), raddr=(‘127.0.0.1‘, 7311)>, (‘127.0.0.1‘, 7311))1819# inp = input(‘请输入要发送的内容:‘)20# con.send(bytes(inp,‘utf8‘))2122 data = con.recv(1024)   # 注意! 为什么用con23print(str(data,utf8))
server 端

  client 端代码:

技术分享图片 技术分享图片
                 1
                #
                author:"LFD"
                 2
                #
                date: 2018/5/14
                 3
                 4
                import
                 socket

                 5
                 6 sk = socket.socket()    # 同样建立一个socket连接。 7print(sk)   #<socket.socket fd=428, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0> 8 910 address = (127.0.0.1,8000) # 代指本机IP地址,8000是端口号1112sk.connect(address)
1314# data = sk.recv(1024)15# print(str(data,‘utf8‘))16 inp = input(请输入您要发送的内容:)
17 sk.send(bytes(inp,utf8))
client 端代码

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 相关方法以及参数介绍:

             1
            sk.bind(address)

             2
             3
            #
            s.bind(address) 将套接字绑定到地址。address地址的格式取决于地址族。在AF_INET下,以元组(host,port)的形式表示地址。
             4
             5
            sk.listen(backlog)

             6
             7
            #
            开始监听传入连接。backlog指定在拒绝连接之前,可以挂起的最大连接数量。
             8
             9
            #
            backlog等于5,表示内核已经接到了连接请求,但服务器还没有调用accept进行处理的连接个数最大为5
            10
            #
            这个值不能无限大,因为要在内核中维护连接队列
            11
            12
            sk.setblocking(bool)

            13
            14
            #
            是否阻塞(默认True),如果设置False,那么accept和recv时一旦无数据,则报错。
            15
            16
            sk.accept()

            17
            18
            #
            接受连接并返回(conn,address),其中conn是新的套接字对象,可以用来接收和发送数据。address是连接客户端的地址。
            19
            20
            #
            接收TCP 客户的连接(阻塞式)等待连接的到来
            21
            22
            sk.connect(address)

            23
            24
            #
            连接到address处的套接字。一般,address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。
            25
            26
            sk.connect_ex(address)

            27
            28
            #
            同上,只不过会有返回值,连接成功时返回 0 ,连接失败时候返回编码,例如:10061
            29
            30
            sk.close()

            31
            32
            #
            关闭套接字
            33
            34
            sk.recv(bufsize[,flag])

            35
            36
            #
            接受套接字的数据。数据以字符串形式返回,bufsize指定最多可以接收的数量。flag提供有关消息的其他信息,通常可以忽略。
            37
            38
            sk.recvfrom(bufsize[.flag])

            39
            40
            #
            与recv()类似,但返回值是(data,address)。其中data是包含接收数据的字符串,address是发送数据的套接字地址。
            41
            42
            sk.send(string[,flag])

            43
            44
            #
            将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。即:可能未将指定内容全部发送。
            45
            46
            sk.sendall(string[,flag])

            47
            48
            #
            将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。
            49
            50
            #
            内部通过递归调用send,将所有内容发送出去。
            51
            52
            sk.sendto(string[,flag],address)

            53
            54
            #
            将数据发送到套接字,address是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。该函数主要用于UDP协议。
            55
            56
            sk.settimeout(timeout)

            57
            58
            #
            设置套接字操作的超时期,timeout是一个浮点数,单位是秒。值为None表示没有超时期。一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作(如 client 连接最多等待5s )
            59
            60
            sk.getpeername()

            61
            62
            #
            返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)。
            63
            64
            sk.getsockname()

            65
            66
            #
            返回套接字自己的地址。通常是一个元组(ipaddr,port)
            67
            68
            sk.fileno()

            69
            70
            #
            套接字的文件描述符
        

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

(升级版)小应用:server 端 和 client 端进行通信。client 端和server 端都可以主动进行关闭,并且当client 端关闭后,server 端可以等待下次连接。

  server 端代码

技术分享图片 技术分享图片
                 1
                #
                author:"LFD"
                 2
                #
                date: 2018/5/14
                 3
                 4
                import
                 socket

                 5
                 6 sk = socket.socket() #什么都不加就可以了,参数已经默认写好了 7#print(sk)   #<socket.socket fd=428, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0> 8 9 address = (127.0.0.1,8000) #回环地址,代表了默认的IP地址就是当前这台电脑的IP地址。 8000是端口号。1011 sk.bind(address) # 绑定了IP地址和端口1213 sk.listen(3)  # 决定着serve端到底可以容纳多少个排队人数。14print(waiting...)
1516#print(con) #(<socket.socket fd=504, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM,17#proto=0, laddr=(‘127.0.0.1‘, 8000), raddr=(‘127.0.0.1‘, 7311)>, (‘127.0.0.1‘, 7311))1819while 1:
20     con, addr = sk.accept()
21print(addr)
22while 1:
23         data = con.recv(1024)   # 注意! 为什么用con24print(....,str(data,utf8))
25ifnot data:break26#    con.close()27#    con,addr = sk.accept()28#    print(addr)29#    continue30         inp = input(请输入要发送的内容:)
31if inp == q:
32break33         con.send(bytes(inp, utf8))
3435     con.close()
server 端代码

  client 端代码

技术分享图片 技术分享图片
                 1
                #
                author:"LFD"
                 2
                #
                date: 2018/5/14
                 3
                 4
                import
                 socket

                 5
                 6 sk = socket.socket()    # 同样建立一个socket连接。 7#print(sk)   #<socket.socket fd=428, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0> 8 910 address = (127.0.0.1,8000) # 代指本机IP地址,8000是端口号1112sk.connect(address)
131415while 1:
16     inp = input(请输入您要发送的内容:)
1718if inp == q:
19break20     sk.send(bytes(inp, utf8))
21     data = sk.recv(1024)
22print(str(data,utf8))
2324 sk.close()
client 端代码

  在进行类型转换的时候:bytes 类型 如果想转换成 int 类型,要经过 str 类型的过度,不可以直接强转成 int 类型,这样是转不成功的。

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

(远程执行命令)小应用:远程执行命令。 client 端 向 server 端发送一个 shell 命令,server 端执行并返回结果。 重点在对文件字节未知的情况下,进行多次发送。 注意粘包现象——数据。  

  cmd_server 端代码

技术分享图片 技术分享图片
                 1
                #
                author:"LFD"
                 2
                #
                date: 2018/5/14
                 3
                 4
                import
                 socket

                 5
                import subprocess # 执行shell命令 6 7 sk = socket.socket() #什么都不加就可以了,参数已经默认写好了 8 9 address = (127.0.0.1,8000) #回环地址,代表了默认的IP地址就是当前这台电脑的IP地址。 8000是端口号。1011 sk.bind(address) # 绑定了IP地址和端口1213 sk.listen(3)  # 决定着serve端到底可以容纳多少个排队人数。14print(waiting...)
1516while 1:
17     con, addr = sk.accept()
18print(addr)
19while 1:
20         data = con.recv(1024)   # 注意! 为什么用con21ifnot data:break22print(....,str(data,utf8))
2324         object = subprocess.Popen(str(data,utf8),shell=True,stdout=subprocess.PIPE)
2526         cmd_result = object.stdout.read()
2728         result_len = bytes(str(len(cmd_result)),utf8)
2930         con.send(result_len)#发送完毕后可能会再等待一下,如果将后一个包的数据一起发送了,就产生了粘包现象。3132         con.recv(1024)  #在两个发送之间添加一个接收阻塞。来解决粘包现象。3334        con.send(cmd_result)
353637     con.close()
cmd_sever

  cmd_client 端代码

技术分享图片 技术分享图片
                 1
                #
                author:"LFD"
                 2
                #
                date: 2018/5/14
                 3
                 4
                import
                 socket

                 5
                 6 sk = socket.socket()    # 同样建立一个socket连接。 7 8 address = (127.0.0.1,8000) # 代指本机IP地址,8000是端口号 910sk.connect(address)
1112while 1:
13     inp = input(请输入您要发送的内容:)
1415if inp == q:
16break17     sk.send(bytes(inp, utf8))
1819     result_len = int(str(sk.recv(100),utf8))
20print(result_len)
2122     sk.send(bytes(ok,utf8))   #做一个隔断,对粘包现象进行处理。2324     data = bytes()
25while len(data) != result_len:
2627         recv = sk.recv(1024)
28         data += recv
2930print(str(data,gbk))
3132 sk.close()
cmd_client

 

二、编码问题

  Python3 中只有两种数据类型。str  、bytes。

  str :unicode   数据类型是str,储存的是 unicode 的编码。

  bytes:十六进制  有utf8 、gbk 编码的bytes 类型。拦住

  由str ---> bytes 叫做编码;

技术分享图片 技术分享图片
                 1
                #
                author:"LFD"
                 2
                #
                date: 2018/5/2
                 3
                 4
                #
                 str -------> bytes
                 5
                 6 s = hello袁浩 7 8 b = bytes(s,utf8)
 9print(b)    #b‘helloxe8xa2x81xe6xb5xa9‘ utf8 规则下的bytes 类型1011 b2 = s.encode(utf8)
12print(b2)   #b‘helloxe8xa2x81xe6xb5xa9‘ 编码方法1314 b3 = s.encode(gbk)
15print(gbk 编码下的Bytes数据,b3)   #gbk 编码下的Bytes数据 b‘helloxd4xacxbaxc6‘16171819# bytes -------> str2021 s = str(b2,gbk)
22print(s)    #   hello琚佹旦  乱码2324#解码方式1:25 s2 = str(b2,utf8)
26print(s2)   #   hello袁浩  str 类型2728#解码方式2:29 s3 = b2.decode(utf8)
30print(s3)   #   hello袁浩3132#解码方式3:33 s4 = b3.decode(gbk)
34print(s4) #  hello袁浩
编码实例 

 

 

 

 

 

 

原文:https://www.cnblogs.com/jinzejun/p/9037684.html


【说明】本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:254677821)!