Python Socket

Socket:

    网络7层模型:

        1.物理层:主要定义物理传输设备标准,如网线的接口类型,各种传输介质的传输速率等。

        2.数据链路层:主要将物理层接受的数据进行MAC地址的封装与解封。

        3.网络层:主要将从下层接收到的数据进行IP地址的封装与解封。

        4.传输层:定义了一些传输数据的协议和端口号。

        5.会话层:通过传输层建立数据传输的通路。

        6.表示层:主要是进行对接收的数据进行解释加密与解密,压缩与解压。

        7.应用层:一些终端的应用。

       

    UDP特点:

        .面向无连接:传输数据之前源端与目的端不需要建立连接

        .每个数据报的大小都限制在64k(8字节)以内

        .面向报文的不可靠协议

        .传输速率快,效率高

        .现实生活实例:实时在线聊天,视频会议

    TCP特点:

        .面向连接:传输数据之前需要建立连接

        .在连接过程中进行大量数据传输

        .通过三次握手的方式完成连接,是安全可靠的连接

        .传输速度慢,效率低

       

    socket创建:

        sk.socket.socket(socket.AF_INET,socket.SCOK_STREAM,0)

        1.地址簇

            socket.AF_INET  IPV4(默认)

            socket.AF_INET6 IPV6

            socket.AF_UNIX 只能用于单一的unix系统进程通信

        2.类型

            socket.SOCK_STREAM 流式socket ,for TCP(默认)

            socket.SOCK_DGRAM  数据报socket , for UDP

       

    socket通信流程:

       

        sk.bind(address)->sk.bind(('127.0.0.1',8000))

            #将套接字绑定到地址

        sk.listen(backing)->sk.listen(5)

            #开始监听传入连接,backing 可挂起的最大连接数量

        sk.setblocking(False)

            #是否阻塞,默认True,设置False时,accept和recv时一旦无数据,则报错。

        conn,addr = sk.accept()

            #接受并返回(conn,address),其中conn时套接字对象

        sk.connect(('127.0.0.1',8000))

            #连接到addr处的套接字,客户端

        sk.connect_ex(('127.0.0.1'),8000)

            #连接到addr处的套接字,连接成功时返回0,客户端

        sk.close()

            #关闭套接字

        sk.recv(bufsize,[flag])

            #接受套接字的数据,bufsize制定最多可以接收的数量,flag提供有关消息的其他信息

        sk.recvfrom(bufsize,[flag])

            #返回数据和发送数据的套接字地址 data,sddr = sk.recvfrom()

        sk.send(string,[flag])

            #将string中的数据发送到连接的套接字

        sk.sendall(string,[flag])

            #将string数据全部发送,内部通过递归调用send()方法

        sk.sendto(string,[flag],address)

            #将数据发送到之地address的套接字,该函数主要用于UDP协议

        sk.settimeout(timeout)

            #设置套接字操所的超时时间,timeout是一个浮点数,单位是秒

        sk.getpeername()

            #返回套接字的远程地址,返回元祖类型

        sk.getsockname()

            #返回套接字自己的地址

        sk.fileno()

            #套接字的文件描述符

       

        #阻塞式socket

        socket_sever.py

            import socket

            sk = socket.socket()

            ip_port = ('127.0.0.1',8888)

            sk.bind(ip_port)

            sk.listen(5)

            while True:

                print('wait .....')

                conn,addr = sk.accept()

                while True:

                    try:

                        data = conn.recv(1024)

                    except Exception as e:

                        print('对方已经下线!')

                        break

                    print(str(data,encoding='utf8'))

                    while True:

                        inp = input('inp>>>:')

                        if len(inp)>0:

                            break

                    if inp == 'q':

                        conn.close()

                        break

                    conn.send(bytes(inp,encoding='utf8'))

            sk.close()

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

        socket_client.py

            import  socket

            sk = socket.socket()

            ip_port = ('127.0.0.1',8888)

            sk.connect(ip_port)

            while True:

                inp = input('inp>>:')

                if inp == 'q' or inp == '':

                    break

                sk.send(bytes(inp,encoding='utf8'))

                try:

                    data = sk.recv(1024)

                except Exception as e:

                    print('对方已经下线!')

                    break

                print(str(data,encoding='utf8'))

            sk.close()

 

        #并发,非阻塞式

        server.py

        import socketserver

            class MyServer(socketserver.BaseRequestHandler):

                def handle(self):

                    print('启动服务端:')

                    while True:

                        conn = self.request

                        print(self.client_address)

                        while True:

                            client_data = conn.recv(1024)

                            print(str(client_data,encoding='utf8'))

                            sever_response = input('>>>')

                            conn.sendall(bytes(sever_response,encoding='utf8'))

                        conn.close()

            if __name__ == '__main__':

                server = socketserver.ThreadingTCPServer(('127.0.0.1',8899),MyServer)

                server.serve_forever()

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

        client.py

        import socket

            sk = socket.socket()

            ip_port = ('127.0.0.1',8899)

            sk.connect(ip_port)

            print('客户端启动')

            while True:

                inp = input('>>>')

                sk.sendall(bytes(inp,encoding='utf8'))

                server_response = sk.recv(1024)

                print(str(server_response,encoding='utf8'))

                if inp == 'q':

                    break

            sk.close()

                

        注意:

            1.一发一收

            2.解决粘包的方式,就是在发送字符长度的时候,等待接收一个对方传过来的信号

            3.5个server类

                .BaseServer

                    .TCPServer ->UnixSreamServer (unix 系统下的TCP)

                    .UDPServer ->UnixDatagramServer (unix 系统下的UDP)

            4.socketserver 并发

                .socketserver.ForkingTCPServer  (基于多进程的并发)

                .socketserver.ForkingUDPServer

                .socketserver.ThreadingTCPServer (基于多线程的并发)

                .socketserver.ThreadingUDPServer

posted @ 2018-05-02 15:55  mihon  阅读(20)  评论(0)    收藏  举报