Python套接字编程(tcp的socket, 流式套接字)

1. 套接字介绍

  1. 套接字 : 实现网络编程进行数据传输的一种技术手段
  2. Python实现套接字编程:import socket
  3. 套接字分类
    流式套接字(SOCK_STREAM): 以字节流方式传输数据,实现tcp网络传输方案。(面向连接–tcp协议–可靠的–流式套接字)
    数据报套接字(SOCK_DGRAM):以数据报形式传输数据,实现udp网络传输方案。(无连接–udp协议–不可靠–数据报套接字)

2. tcp套接字编程

一 服务端流程

socket---->bind---->listen---->accept---->send/recv---->close

  1. 创建套接字
    sockfd=socket.socket(socket_family=AF_INET,socket_type=SOCK_STREAM,proto=0)
    功能:创建套接字
    参数: socket_family 网络地址类型, AF_INET表示ipv4
    socket_type 套接字类型:
    SOCK_STREAM(流式)
    SOCK_DGRAM(数据报)
    proto 通常为0 选择子协议
    返回值: 套接字对象
  2. 绑定地址
    本地地址 : ‘localhost’ , ‘127.0.0.1’
    网络地址 : ‘172.40.91.185’
    自动获取地址: ‘0.0.0.0’
    sockfd.bind(addr)
    在这里插入图片描述
    功能: 绑定本机网络地址
    参数: 二元元组 (ip,port)
    pythonNet
    (‘0.0.0.0’,8888)
  3. 设置监听
    sockfd.listen(n)
    功能 : 将套接字设置为监听套接字,确定监听队列大小
    参数 : 监听队列大小
  4. 等待处理客户端连接请求
    connfd,addr = sockfd.accept()
    功能: 阻塞等待处理客户端请求
    返回值:
    connfd 客户端连接套接字
    addr 连接的客户端地址
  5. 消息收发
    data = connfd.recv(buffersize)
    功能 : 接受客户端消息
    参数 :每次最多接收消息的大小
    返回值: 接收到的内容
    n = connfd.send(data)
    功能 : 发送消息
    参数 :要发送的内容 bytes格式
    返回值: 发送的字节数
  6. 关闭套接字
    sockfd.close()
    功能:关闭套接字
"""
tcp_server.py 服务端
"""
import socket

# 创建tcp套接字
sockfd = socket.socket(socket.AF_INET,
                       socket.SOCK_STREAM)

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

# 设置监听
sockfd.listen(3)

# 处理客户端链接
print("Waiting for connect...")
connfd,addr = sockfd.accept()
print("Connect from",addr)

# 收发消息
data = connfd.recv(1024)
print("Recv:",data)
n = connfd.send(b"OK\n") # 发送字节串

# 关闭套接字
connfd.close()
sockfd.close()
# 客户端测试命令 telnet 127.0.0.1 8888

tcp服务端的练习

"""
练习 : 选择一张图片,从客户端上传到服务端

       温馨提示: 客户端读取图片的内容
                 将内容发送给服务端
                 服务端接受图片内容
                 保存在服务端某个位置
"""
from socket import *
from time import localtime

# 存在这里
SAVE_PATH = "/home/tarena/图片/"

s = socket()
s.bind(('127.0.0.1',8888))
s.listen(3)

c,addr = s.accept()
print("Connect from",addr)

# 打开文件
tmp = localtime()
img = "%s-%s-%s.jpg"%tmp[:3]
f = open(SAVE_PATH+img,'wb')

#接受图片
while True:
    data = c.recv(1024)
    if not data:
        break
    f.write(data)

f.close()
c.close()
s.close()

客户端流程

socket----> connect ----> send/recv ----> close

  1. 创建套接字
    注意:只有相同类型的套接字才能进行通信
  2. 请求连接
    sockfd.connect(server_addr)
    功能:连接服务器
    参数:元组 服务器地址
  3. 收发消息
    注意: 防止两端都阻塞,recv send要配合
  4. 关闭套接字

tcp 套接字数据传输特点

tcp连接中当一端退出,另一端如果阻塞在recv,此时recv会立即返回一个空字串
tcp连接中如果一端已经不存在,仍然试图通过send发送则会产生BrokenPipeError
一个监听套接字可以同时连接多个客户端,也能够重复被连接

网络收发缓冲区

  1. 网络缓冲区有效的协调了消息的收发速度
  2. send和recv实际是向缓冲区发送接收消息,当缓冲区不为空recv就不会阻塞。

tcp粘包

原因:tcp以字节流方式传输,没有消息边界。多次发送的消息被一次接收,此时就会形成粘包。
影响:如果每次发送内容是一个独立的含义,需要接收端独立解析此时粘包会有影响。
处理方法

  1. 人为的添加消息边界
  2. 控制发送速度
"""
tcp_client.py  tcp客户端
"""

from socket import *

# 创建tcp套接字
sockfd = socket()  # 默认参数--》 tcp

# 连接服务器
server_addr = ('127.0.0.1',8887) # 服务端地址
sockfd.connect(server_addr)

while True:
    data = input("Msg>>")
    if not data:
        break
    # 发送给服务端
    sockfd.send(data.encode()) # 转换为字节串
    # if data == '##':
    #     break
    data = sockfd.recv(1024)
    print("Server:",data.decode()) # 打印字符串

# 关闭套接字
sockfd.close()
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值