Python UDP Socket编程
客户端
from socket import *
serverName='192.168.3.8'
serverPort=12345
clientSocket=socket(AF_INET,SOCK_DGRAM)
while 1:
message=input().encode()
clientSocket.sendto(message,(serverName,serverPort))
modifiedMessage,serverAddress=clientSocket.recvfrom(2048)
print(modifiedMessage)
clientSocket.close()
逐行解释
serverName='192.168.3.8' //指定要连接到服务端的IP地址
serverPort=12000 //指定要连接到服务端的12000端口
clientSocket=socket(AF_INET,SOCK_DGRAM) //调用socket函数,设置网络层使用IPv4协议,传输层使用UDP协议
message=input().encode() //获取键盘输入,并且缺省参数时按照utf-8编码,如果message不编码则后面sendto函数会报错
clientSocket.sendto(message,(serverName,serverPort))//将message送往serverName:serverPort
modifiedMessage,serverAddress=clientSocket.recvfrom(2048)//服务端从客户端接到消息并修改后返回客户端
print(modifiedMessage)//客户端将从服务端接收到的消息打印
clientSocket.close()//关闭套接字,关闭进程
函数详解
socket(family=-1, type=-1, proto=-1, fileno=None) -> socket object
socket(family=AF_INET, type=SOCK_STREAM, proto=0) -> socket object socket(family=-1, type=-1, proto=-1, fileno=None) -> socket object
Open a socket of the given type. The family argument specifies the address family;
打开一个给定类型的socket.形参family规定了IP地址类型
it defaults to AF_INET.
IP地址类型缺省位AF_INET类型(IPv4类型)
The type argument specifies whether this is a stream (SOCK_STREAM, this is the default) or datagram (SOCK_DGRAM) socket.
type形参规定了该socket是一个流类型(TCP)或者是一个数据报类型 (UDP),缺省为流类型
The protocol argument defaults to 0,
协议参数缺省是0
specifying the default protocol.
规定缺省时的协议
Keyword arguments are accepted.
允许关键字参数
The socket is created as non-inheritable.
创建好的socket是不可继承的
When a fileno is passed in, family, type and proto are auto-detected,unless they are explicitly set.
当传入fileno参数时,family,type,proto是自动探测的,除非他们被显式地给出
A socket object represents one endpoint of a network connection.
一个socket对象代表网络连接的一端
socket是一个预定义类,socket()
会调用该类的构造函数
def __init__(self, family=-1, type=-1, proto=-1, fileno=None):
# For user code address family and type values are IntEnum members, but
# for the underlying _socket.socket they're just integers. The
# constructor of _socket.socket converts the given argument to an
# integer automatically.
if fileno is None:
if family == -1:
family = AF_INET
if type == -1:
type = SOCK_STREAM
if proto == -1:
proto = 0
_socket.socket.__init__(self, family, type, proto, fileno)
self._io_refs = 0
self._closed = False
self是当前对象指针
参数含义及类型:
family | 含义 |
---|---|
AF_UNIX,AF_LOCAL | 本地 |
AF_INET | IPv4 |
AF_INET6 | IPv6 |
AF_PACKET | 链路层通信 |
type | |
---|---|
SOCK_STREAM=1 | TCP |
SOCK_DGRAM=2 | UDP |
SOCK_RAW=3 | |
SOCK_RDM=4 | |
SOCK_SEQPACKET=5 | |
SOCK_DCCP=6 | |
SOCK_PACKET=7 |
创建socket对象后并没有和服务端建立连接,本地也不会建立进程
sendto(data[, flags], address) -> count
Like send(data, flags) but allows specifying the destination address.
类似send(data,flags)函数,但是允许指定目标地址
For IP sockets, the address is a pair (hostaddr, port).
对于IP类型的sockets,address参数是一个ip,port对
recvfrom(buffersize[, flags]) -> (data, address info)
Receive up to buffersize bytes from the socket.
从套接字接收最多buffersize大小的字节
For the optional flags argument, see the Unix manual.
对于可选的flags参数,见Unix手册
When no data is available, block until at least one byte is available or until the remote end is closed.
当没有数据时,阻塞,除非接收到一个字节或者远程终端关闭
When the remote end is closed and all data is read, return the empty string.
当远程终端关闭并且所有数据都已被读取,返回空字符串
also return the sender’s address info.
作为接收方,返回发送方的地址信息address info
服务端
from socket import *
serverPort=12345
serverSocket=socket(AF_INET,SOCK_DGRAM)
serverSocket.bind(('192.168.3.8',serverPort))
print('ready')
while 1:
message,clientAddress=serverSocket.recvfrom(2048)
modifiedMessage=message.upper()
print(modifiedMessage)
serverSocket.sendto(modifiedMessage,clientAddress)
函数作用
bind(address)
Bind the socket to a local address.
将socket与本地地址绑定
For IP sockets, the address is a pair (host, port);
对于IP类型的socket,address参数是(ip地址,端口号)对
the host must refer to the local host.
host参数必须是本机的地址
For raw packet sockets the address is a tuple (ifname, proto [,pkttype [,hatype [,addr]]])
对于raw packet类型的socket,address参数是一个元组
serverSocket.bind(('192.168.3.8',serverPort))//将套接字和ip地址192.168.3.8(服务端所在主机的ip),端口12000绑定
运行结果
wireshark抓包观察
从客户端向服务端发送hello
客户端在192.168.3.2:57445
服务端在192.168.3.8:12345