python基础-socket初识、udp通信、udp数据报协议

socket是什么

Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。
这里写图片描述

socket工作流程

这里写图片描述

先从服务器端说起。服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束

tcp通信

接下来我们就实现一个socket通讯例子,就那tcp举例

服务端:

import socket
#获取socket对象
# AF_INET:IPv4 网络协议的套接字类型
# SOCK_STREAM:提供面向连接的稳定数据传输,即TCP协议
mServerSocket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#解决端口占用问题
mServerSocket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)

#绑定ip+端口
mServerSocket.bind(("127.0.0.1",8080))
mServerSocket.listen(5)
print("start...")
conn,addr = mServerSocket.accept()
# print(conn,addr)

#最大接收的字节数
data = conn.recv(1024)
print("recv:",data.decode("utf-8"))

conn.send(data.upper())

conn.close()
mServerSocket.close()

客户端:

import socket
mClientSocket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
mClientSocket.connect(("127.0.0.1",8080))
mClientSocket.send("hello 套接字".encode("utf-8"))

data = mClientSocket.recv(1024)
print("recv:",data.decode("utf-8"))
mClientSocket.close()

运行服务端,在运行客户端
服务端输出如下:

E:\python\python_sdk\python.exe E:/python/py_pro/server.py
start...
recv: hello 套接字

Process finished with exit code 0

客户端输出如下:

E:\python\python_sdk\python.exe E:/python/py_pro/client.py
recv: HELLO 套接字

Process finished with exit code 0
udp通信

udp是无链接的,先启动哪一端都不会报错
服务端:

from socket import *

server=socket(AF_INET,SOCK_DGRAM)
server.bind(('127.0.0.1',8083))

while True:
    data,client_addr=server.recvfrom(1024)
    print('客户端的数据: ',data)
    server.sendto(data.upper(),client_addr)

客户端:

from socket import *

client=socket(AF_INET,SOCK_DGRAM)

while True:
    msg=input('>>: ').strip()

    client.sendto(msg.encode('utf-8'),('127.0.0.1',8083))
    data,server_addr=client.recvfrom(1024)
    print(data.decode('utf-8'))

客户端输入:

>>: wyf
WYF
>>: 

服务端输出:

E:\python\python_sdk\python.exe "E:/python/py_pro/2 基于udp协议的套接字通信/服务端.py"
客户端的数据:  b'wyf'
udp数据报协议

UDP(user datagram protocol,用户数据报协议)是无连接的,面向消息的,提供高效率服务。不会使用块的合并优化算法,, 由于UDP支持的是一对多的模式,所以接收端的skbuff(套接字缓冲区)采用了链式结构来记录每一个到达的UDP包,在每个UDP包中就有了消息头(消息来源地址,端口等信息),这样,对于接收端来说,就容易进行区分处理了。 即面向消息的通信是有消息保护边界的。
udp的recvfrom是阻塞的,一个recvfrom(x)必须对唯一一个sendinto(y),收完了x个字节的数据就算完成,若是y>x数据就丢失,这意味着udp根本不会粘包,但是会丢数据,不可靠

第一种情况

服务端:

from socket import *

server=socket(AF_INET,SOCK_DGRAM)
server.bind(('127.0.0.1',8081))

data,client_addr=server.recvfrom(11111111)
print('数据2: ',data)

客户端:

from socket import *

client=socket(AF_INET,SOCK_DGRAM)

client.sendto('hello'.encode('utf-8'),('127.0.0.1',8081))
client.sendto('world'.encode('utf-8'),('127.0.0.1',8081))

启动客户端,服务端

数据2:  b'hello'
第二种情况

如果将服务端代码改成如下:

from socket import *

server=socket(AF_INET,SOCK_DGRAM)
server.bind(('127.0.0.1',8081))


data,client_addr=server.recvfrom(11111111)
print('数据1: ',data)


data,client_addr=server.recvfrom(11111111)
print('数据2: ',data)

启动客户端、服务端会输出如下:

数据1:  b'hello'
数据2:  b'world'
第三种情况

如果将服务端改成如下:

from socket import *

server=socket(AF_INET,SOCK_DGRAM)
server.bind(('127.0.0.1',8081))


data,client_addr=server.recvfrom(11111111)
print('数据1: ',data)


data,client_addr=server.recvfrom(1)
print('数据2: ',data)

会如下报错

E:\python\python_sdk\python.exe "E:/python/py_pro/3 数据报协议/服务端.py"
Traceback (most recent call last):
数据1:  b'hello'
  File "E:/python/py_pro/3 数据报协议/服务端.py", line 11, in <module>
    data,client_addr=server.recvfrom(1)
OSError: [WinError 10040] 一个在数据报套接字上发送的消息大于内部消息缓冲区或其他一些网络限制,或该用户用于接收数据报的缓冲区比数据报小。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Python Socket UDP通信是一种基于UDP协议的网络通信方式,它可以实现点对点的数据传输,具有高效、快速、简单等优点。在Python中,我们可以使用socket模块来实现UDP通信,通过创建socket对象、绑定IP地址和端口号、发送和接收数据等操作,实现网络通信。同时,Python Socket UDP通信也可以应用于各种场景,如网络游戏、实时通信数据采集等。 ### 回答2: Python socket库是Python标准库的一部分,用于实现网络通信。其使用非常简单,主要是调用socket模块下的一些方法即可完成常见网络通信任务。在Python中,UDP通信是基于socket进行实现的。 UDP是一种无连接协议通信双方之间没有建立可靠的连接。虽然UDP不如TCP那样可靠,但是它的实时性好,适合于需要实时传输数据的场景。UDP通信方式是通过数据进行传输,每个数据最大长度为65,535个字节。 在Python中,通过socket模块创建UDP套接字(socket),然后通过该套接字实现UDP通信。创建UDP套接字的方法为: ``` import socket server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) ``` 其中,`AF_INET`代表IPv4协议,`SOCK_DGRAM`代表使用UDP数据协议。 接下来,就可以使用该套接字实现UDP通信了。 在进行UDP通信时,需要注意以下几点: 1. 给套接字绑定IP地址和端口号 在Python中,使用`bind()`方法将IP地址和端口号绑定到套接字上,以便可以接收来自这个地址和端口的消息。例如: ``` server_socket.bind(('127.0.0.1', 9999)) ``` 其中,`127.0.0.1`表示本机IP地址,`9999`表示端口号。 2. 发送数据 通过套接字的`sendto()`方法向指定的IP地址和端口号发送数据。例如: ``` server_socket.sendto('hello, world!', ('127.0.0.1', 8888)) ``` 其中,`'hello, world!'`表示需要发送的数据,`('127.0.0.1', 8888)`表示目标IP地址和端口号。 3. 接收数据 通过套接字的`recvfrom()`方法接收来自指定IP地址和端口号的数据。例如: ``` data, addr = server_socket.recvfrom(1024) ``` 其中,`1024`表示接收数据的缓冲区大小。 4. 关闭套接字 在UDP通信完成后,需要使用`close()`方法关闭套接字。例如: ``` server_socket.close() ``` 以上就是Python socket库进行UDP通信的基本步骤。值得注意的是,在实际的网络通信中可能会遇到各种异常情况,例如网络故障、套接字参数错误等,需要合理的使用异常处理机制,以保证程序的正确性和稳定性。 ### 回答3: Python Socket UDP通信是指使用socket库中的UDP协议进行数据传输的一种通信方式。UDP(User Datagram Protocol,用户数据协议)是在IP协议基础上实现的一种无连接的传输层协议UDP协议提供了无状态的、不可靠的数据传输服务,可以快速传输数据包,但是不能提供可靠的数据传输服务,因此在网络上的应用较少,通常用于需要快速传输而不需要可靠性保证的应用场景。 Python中可以通过使用socket库中的socket类来进行UDP通信。在使用socket进行UDP通信时,需要指定socket的类型为SOCK_DGRAM(表示UDP协议),同时需要指定目标地址和端口号。发送数据时,使用sendto()方法将数据打包发送到指定的目标地址和端口号。接收数据时,使用recvfrom()方法接收数据,并返回发送方的地址和端口号。 下面是一个简单的Python Socket UDP通信的示例代码: ```python import socket # 创建UDP socket udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 目标地址和端口号 target_addr = ('127.0.0.1', 8888) # 发送数据 data = 'Hello, UDP!' udp_socket.sendto(data.encode(), target_addr) # 接收数据 recv_data, addr = udp_socket.recvfrom(1024) print('Received from {}: {}'.format(addr, recv_data.decode())) # 关闭socket udp_socket.close() ``` 在这个示例代码中,首先创建了一个UDP socket,指定了目标地址和端口号为127.0.0.1和8888。然后使用sendto()方法将字符串“Hello, UDP!”发送到目标地址和端口号。接着使用recvfrom()方法接收数据,返回发送方的地址和端口号,将接收到的数据打印出来。最后关闭socket。 需要注意的是,在UDP通信中,由于UDP协议的不可靠性,发送方无法确定数据是否被接收方接收到。如果需要可靠的数据传输服务,应该使用TCP协议进行通信

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值