python基础--socket套接字、粘包问题

本地回环地址:127.0.0.1

简易版服务端:

import socket
?
server = socket.socket()  # 就比如买了一个手机
server.bind(("127.0.0.1",8080))  # bind中绑定的是IP地址和端口号,注意是一个元组,就比如,将手机卡,插入了手机
server.listen(5)  # 半连接池,最大等待连接数为5个,就比如开机
conn,address = server.accept()  # 接听电话等着别人给你打电话
?
date = conn.recv(1024)  # 听别人说话,接收1023个字节数
print(date)
conn.send(b"hello")  # 给别人回话
?
?
conn.close()  # 挂断电话
server.close()  # 关机

简易版客户端:

import socket
?
client = socket.socket()  #拿电话
client.connect(("127.0.0.1",8080))  #绑定的是IP地址和端口号,也是一个元组 拨号
?
client.send(b"hello")  # 对别人发消息
?
date = client.recv(1024)  #接收别人说话,没次接收1024个字节
print(date)
?
client.close()  # 挂电话

注意:在写服务端和客户端的时候send和recv需要一一对应,不能再两边都出现,recv是跟内存要数据,至于数据的来源无需考虑

粘包:

服务端:

import socket
?
server = socket.socket()  # 就比如买了一个手机
server.bind(("127.0.0.1",8088))  # bind中绑定的是IP地址和端口号,注意是一个元组,就比如,将手机卡,插入了手机
server.listen(5)  # 半连接池,最大等待连接数为5个,就比如开机
conn,address = server.accept()  # 接听电话等着别人给你打电话
?
date = conn.recv(1024)  # 听别人说话,接收1023个字节数
print(date)
date = conn.recv(1024)  # 听别人说话,接收1023个字节数
print(date)
?
?
conn.close()  # 挂断电话
server.close()  # 关机

客户端:

import socket
?
client = socket.socket()  #拿电话
client.connect(("127.0.0.1",8088))  #绑定的是IP地址和端口号,也是一个元组 拨号
?
client.send(b"hello")  # 对别人发消息
client.send(b"hello")  # 对别人发消息
?
?
client.close()  # 挂电话

服务端打印结果:

b‘hellohello‘

这是因为tcp协议会将时间间隔短的,和文件大小小的会一次打包发送给对方

解决粘包问题:

struct模块:

import struct
?
?
print("--------------------------1--------------------------")
msg = "asdasdasdasdasd"
print("原字符串的长度")
print(len(msg))
?
handler = struct.pack("i",len(msg))
print("创建报头的长度")
print(len(handler))
?
?
res = struct.unpack("i",handler)[0]
print("解报头过后的长度")
print(res)
?
?
?
?
?
print("--------------------------2--------------------------")
?
msg1 = "asdasdasdasdasdasdasdasd"
print("原字符串的长度")
print(len(msg1))
?
handler1 = struct.pack("i",len(msg1))
print("创建报头的长度")
print(len(handler1))
?
?
res1 = struct.unpack("i",handler1)[0]
print("解报头过后的长度")
print(res1)
?
"""
--------------------------1--------------------------
原字符串的长度
15
创建报头的长度
4
解报头过后的长度
15
--------------------------2--------------------------
原字符串的长度
24
创建报头的长度
4
解报头过后的长度
24
"""

我们可以将报头发过去,然后解报头,就可以知道原来数据的大小,如果这个字节大小比我们接受的大,我们就可以一直让它接收,直到接收完成为止,

服务端:

import json
import os
import socket
import struct

server_path = r‘/Users/mac/Documents/client-server/server_movie‘

server = socket.socket()

ip_port = (‘127.0.0.1‘, 8080)

server.bind(ip_port)

server.listen(5)

conn, addr = server.accept()
while 1:

    head_len = conn.recv(4)

    head_len = struct.unpack(‘i‘, head_len)[0]

    json_head = conn.recv(head_len).decode(‘utf-8‘)

    head = json.loads(json_head)

    file_size = head[‘file_size‘]

    with open(os.path.join(server_path, head[‘file_name‘]), ‘wb‘) as f:
        while file_size:
            if file_size >= 1024:
                content = conn.recv(1024)
                f.write(content)
                file_size -= 1024
            else:
                content = conn.recv(file_size)
                f.write(content)
                break

客户端:

import os
import socket
import json
import struct

client = socket.socket()

ip_port = (‘127.0.0.1‘, 8080)

client.connect(ip_port)

head = {
    ‘file_path‘: r‘/Users/mac/Documents/client-server/client_movie‘,
    ‘file_name‘: None,
    ‘file_size‘: None
}
movie_list = os.listdir(head[‘file_path‘])

while 1:
    for i, m in enumerate(movie_list, 1):
        print(‘%s --> %s‘ % (i, m))
    choice = input(‘please input movie number:>>‘).strip()
    if choice.isdigit():
        choice = int(choice)
        if choice in range(1, len(movie_list) + 1):
            movie_name = movie_list[choice - 1]
            head[‘file_name‘] = movie_name
            head[‘file_size‘] = os.path.getsize(os.path.join(head[‘file_path‘], head[‘file_name‘]))
            json_head = json.dumps(head).encode(‘utf-8‘)
            bytes_head = len(json_head)
            pack_head = struct.pack(‘i‘, bytes_head)
            client.send(pack_head)
            client.send(json_head)
            file_size = head[‘file_size‘]
            with open(os.path.join(head[‘file_path‘], head[‘file_name‘]), ‘rb‘) as f:
                while file_size:
                    if file_size >= 1024:
                        content = f.read(1024)
                        client.send(content)
                        file_size -= 1024
                    else:
                        content = f.read(file_size)
                        client.send(content)
                        print("finish")
                        break
        else:
            print(‘index out of range‘)
    else:
        print(‘input number...‘)

原文地址:https://www.cnblogs.com/tulintao/p/11318594.html

时间: 2024-11-09 05:54:59

python基础--socket套接字、粘包问题的相关文章

python之socket(套接字)

一.客户端/服务器架构 1.1基本概念 客户端/服务器架构即:C/S架构,包括: (1)硬件C/S架构(打印机) (2)软件C/S架构(Web服务器) 1.2举例 生活中的C/S架构:饭店为S端,所有食客C端 二.TCP/udp/osi七层 2.1TCP/UDP协议 TCP(Transmission Control Protocol)可靠的.面向连接的协议(eg:打电话).传输效率低全双工通信(发送缓存&接收缓存).面向字节流.使用TCP的应用:Web浏览器:电子邮件.文件传输程序. UDP(U

Python开发基础----socket套接字基础2

基于UDP的socket 面向无连接的不可靠数据传输,可以没有服务器端,只不过没有服务器端,发送的数据会被直接丢弃,并不能到达服务器端 1 #客户端 2 import socket 3 ip_port=('127.0.0.1',8080) 4 BUFSIZE=1024 5 sock_client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) #SOCK_DGRAM就是UDP 6 while True: 7 msg=input('>>').str

tcp套接字粘包解决办法

粘包只会出现在tcp,udp传输不会产生粘包现象.解决粘包的原理就是服务器预先向客户端发送客户端即将获取文件的大小. 第一版解决方案: 服务器: 1 # Author : Kelvin 2 # Date : 2019/2/2 17:38 3 from socket import * 4 import subprocess 5 6 ip_conf = ("127.0.0.1", 8888) 7 buffer_capacity = 1024 8 tcp_server = socket(AF

Python开发基础-Day23try异常处理、socket套接字基础1

异常处理 错误 程序里的错误一般分为两种: 1.语法错误,这种错误,根本过不了python解释器的语法检测,必须在程序执行前就改正 2.逻辑错误,人为造成的错误,如数据类型错误.调用方法错误等,这些解释器是不会进行检测的,只有在执行的过程中才能抛出的错误 异常 异常是python解释器在运行程序的过程中遇到错误所抛出的信息,如: Python异常种类: 常用异常: 1 AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x 2 IOError 输入/输出异

Python开发基础----异常处理、socket套接字基础1

异常处理 错误 程序里的错误一般分为两种: 1.语法错误,这种错误,根本过不了python解释器的语法检测,必须在程序执行前就改正 2.逻辑错误,人为造成的错误,如数据类型错误.调用方法错误等,这些解释器是不会进行检测的,只有在执行的过程中才能抛出的错误 异常 异常是python解释器在运行程序的过程中遇到错误所抛出的信息,如: Python异常种类: 常用异常: 1 AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x 2 IOError 输入/输出异

python基础之try异常处理、socket套接字基础part1

异常处理 错误 程序里的错误一般分为两种: 1.语法错误,这种错误,根本过不了python解释器的语法检测,必须在程序执行前就改正 2.逻辑错误,人为造成的错误,如数据类型错误.调用方法错误等,这些解释器是不会进行检测的,只有在执行的过程中才能抛出的错误 异常 异常是python解释器在运行程序的过程中遇到错误所抛出的信息,如: Python异常种类: 常用异常: 1 AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x 2 IOError 输入/输出异

Socket 套接字和解决粘包问题

---恢复内容开始--- Socket 套接字: 什么是socket: Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socket其实 就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口 就是全部,让Socket去组织数据,以符合指定的协议. socket在OSI模型中的位置 二为什么需要socket 在标准的OIS模型中并没有规定说必须有socket层,也就是说不使用socket也能完成通讯,是的,的

网络编程 TCP协议:三次握手,四次回收,反馈机制 socket套接字通信 粘包问题与解决方法

TCP协议:三次握手,四次挥手 TCP协议建立双向通道. 三次握手, 建连接: 1:客户端向服务端发送建立连接的请求 2:服务端返回收到请求的信息给客户端,并且发送往客户端建立连接的请求 3:客户端接收到服务端发来的请求,返回接成功给服务端,完成双向连接 第一客戶向服务端发送请求,请求建立连接 服务端同客户端的请求,并同时向客户端发送建立 连接的请求,最后客户端同意后建立 双向连接. C ----> S C <---- S - 反馈机制: 客户端往服务端发送请求,服务端必须返回响应, 告诉客户

Python socket 套接字实现通信

首先:我们介绍一下socket什么是socket: 1. socket 在操作系统中它是处于应用层与传输层的抽象层,它是一组操作起来非常简单的接口(接收数据的),此接口接受数据之后交个操作系统 那么为什么?直接给操作系统不是更方便吗?那么你就想错了 因为操作系统的接口远比我们想象的要丑陋复杂,使用操作系统交换数据,非诚繁琐,,开发者们只能想办法让一个中间人和他们打交道,来简单的实现数据交换,那么就是socket套接字.它的作用就是:与操作系统之间数据交换将这些繁琐的操作,进行高度化封装,和简化,