Python 自学笔记 总结 3.0 Socket模块

二.Socket模块

 1.1 UDP套接字

        应用层的一种编程方法

socket( ) 创建套接字
bind ( ) 绑定IP端口
sendto ( ) 发送消息
recvfrom ( ) 接受消息
close( ) 关闭套接字
decode ( ) 解码

服务端编写 

#模块导入
from socket import *

#声明服务端IP,端口
ADDR=('0.0.0.0',8888)

#创建udp套接字 Sock_DGRAM 表示选择的是UDP套接字
udp_socket=socket(AF_INET,SOCK_DGRAM)

#调用bind绑定地址端口
udp_socket.bind(ADDR)

#接受消息 1024 一次能接受的最大字节数
msg,addr=udp_socket.recvfrom(1024)

#打印消息跟地址 decode( )解码
print('Recv:',addr,msg.decode() )

#关闭套接字
udp_socket.close( )

客户端编写

#导入模块
from socket import *

#确定服务器地址  默认本机IP
ADDR=('127.0.0.1,'8888)

#创建套接字
udp_socket=socket(AF_INET,SOCK_DGRAM)

#接受信息
msg=input('>>:')

#发送给服务器
udp_socket.sendto(msg.encode().ADDR)

#关闭套接字
udp_socket.close()

客户端 循环接受消息 

#客户端循环接受消息
while True:
    #接受消息 1024一次能接受的最大字节,返回是以元祖的形式
    msg,addr=udp_socket.recvfrom(1024)
    #打印消息跟地址 decode()解码
    print('Recv:,'addr,msg.decode())
    #回应消息
    udp_socket.sendto('收到!'.encode( ).addr)
    #约定断开通信的
    if msg==b'bye':
        break

#关闭套接字
udp_socket.close()

 服务端 循环发送消息

#服务端 循环发送消息
while True:
    #接受信息
    msg=input('>>:')
    #发送给服务器
    udp_soket.sendto(msg.encode().ADDR)
    #接受服务器的消息
    data,addr=udp_socket.recvfrom(1024)
    print('来自服务器的消息:,'data.decode())
    #终止服务端循环
    if msg=='bye':
        break

#关闭套接字
udp_socket.close()

 UDP套接字特点:

·可能会出现数据丢失

·传输过程简单,实现容易

·数据以数据包的形式传输

·数据传输效率高

 




1.2 TCP套接字

·面向连接的传输服务

1)提供了可靠的数据传递,传输过程当中无丢失,无失序,无差错,无重复

2)可靠性保障机制(自动完成)

        ·在通信之前需要建立数据连接

        ·确认应答机制

        ·通信结束后正常断开连接

·三次握手

客户端向服务器发送报文请求连接

服务收到请求回复报文可以连接

客户端收到回复再次发送报文建立连接

·四次挥手 

发起方发送报文请求断开

接收方收到请求回复信息收到,并准备断开

接收方准备完成,再次发送表示可以断开

发送方收到确定,发送最终消息完成断开

·tcp套接字细节

1) tcp连接中一端退出,另一端依然阻塞在recv,此时recv会马上返回一个空字符串

2)如果一端已经不存在,任然通过send向其发送数据则会产生Broken Pipe Error

3)一个服务端可以同时连接多个客户端,也能够被重复连接

·TCP编程流程
socket

创建套接字

bind 绑定地址
listen 设置监听
accept 等待处理连接
send/recv 发送/接受 消息
close 关闭连接

TCP服务端编写

#导入模块
from socket import *

#创建套接字 默认是TCP 流式套接字
tcp_socket=socket(AF_INET,SOCK_STREAM)

#绑定地址
tcp_socket.bind(('0.0.0.0,'8888))

#设置监听 listen最多能设置1024 Linux自动配置
#具备了监听的属性,被客户端连接的属性
tcp_socket.listen(5)

#等待处理客户端的连接
#accept阻塞函数 处理客户端连接请求没有连接则阻塞
#connfd 处理该连接的专门套接字
#addr 客户端地址
print('等待客户端连接中...')
connfd,addr=tcp_socket.accept()
print('连接的客户端是:',addr)
#接受处理客户端的信息
data=connfd.recv(1024)
print('消息:',data.decode())
#关闭连接
connfd.close()
tcp_socket.close()

TCP客户端编写 

#导入模块
from socket import *

#创建套接字
tcp_socket=socket()

#连接服务端
tcp_socket.connect(('127.0.0.1',8888))

#发送消息
msg=input('>>:')
tcp_socket.send(msg.encode())

#关闭连接
tcp_socket.close()

 TCP服务端编写 循环

#导入模块
from socket import *

#创建套接字 默认是TCP 流式套接字
tcp_socket=socket(AF_INET,SOCK_STREAM)

#绑定地址
tcp_socket.bind(('0.0.0.0,'8888))

#设置监听 listen最多能设置1024 Linux自动配置
#具备了监听的属性,被客户端连接的属性
tcp_socket.listen(5)

#等待接收客户端的连接
print('等待客户端的连接...')
while True:
    connfd,addr=tcp_socket.accept()
    print('连接的客户端是:'addr)

    接受处理客户端的信息
    data=connfd.recv(1024)
    print('消息:',data.decode())

    #回复客户端
    connfd,send('收到:'.encode())
    connfd.close()

#关闭连接
tcp_socket.close()

TCP客户端编写 循环

#导入模块
from socket import *

#创建套接字
tcp_socket=socket()

#连接服务端
tcp_socket.connect(('127.0.0.1',8888))

#循环发送
while True:
    msg=input('>>:')
    tcp_socket.send(msg.encode())

    #接收服务端的消息
    data=tcp_socket.recv(1024)
    print('服务端:,'data,decode())

#关闭连接
tcp_socket.close()

 




1.3 文件传输服务端/客户端

 exercise_server   文件传输服务端编写

步骤:

1.建立TCP套接字

2.等待客户端内连接

3.接收图片内容

4.保存图片

5.终止连接

#导入模块
from socket import *
import time

#创建套接字
socket=socket()

#绑定IP
socket.listen(5)

#创建connfd
connfd,addr=socket.accept()

#接收客户端的数据
data=connfd.recv(1024*1024)
file_name='%d-%d-%d.jpg'%time.localtime()[:3]
f=open(file_name,'wb')
f.write(data)
f.close()
#关闭连接
connfd.close()
socket.close()

exercise_client        文件传输客户端编写 

步骤:

1.创建套接字

2.连接服务端

3.读取文件内容

4.发送文件内容

5.关闭连接

#导入模块
from socket import *

#创建套接字
socket=socket()

#连接服务端
socket.connect(('127.0.0.1,'8888))

#读入文件内容
f=open('2.jpg','rb')
data=f.read()

#发送内容
socket.send(data)
f.close()
socket.close()

粘包问题?

1.】产生原因

        ·为了解决数据传输中的速率不协调问题,操作系统设置了缓冲区

         ·实际网络工作过程比较复杂,导致消息收发不一致

         ·tcp以字节流方式进行数据传输,在接受的时候不区分消息边界

2.】带来的问题?

        ·如果发送的消息每次都是独立的,需要接收端去独立解析消息时回带来消息误解问题

3.】解决方式

        ·人工设置消息边界

        ·减缓消息发送速度




1.4 使用场景

·tcp 适合对准确要求高,传输数据大的场景

        (1)文件传输:数据下载(电影音乐),上传照片,访问网站

        (2)邮件收发

        (3)点对点数据传输:登录,远程,红包,一对一聊天

·udp 适合可靠性要求相对不高,传输自由的场景

        (1)视频流:直播,视频聊天

        (2)广播:网络广播,群发消息

        (3)实时性要求高:游戏等


你可能感兴趣的:(python自学,python,学习,tcp/ip)