python网络编程 socket实现TCP,UDP数据收发

Socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯。
Python 中,我们用 socket()函数来创建套接字,语法格式如下:

socket.socket([family[, type[, proto]]])
参数意义如下:
family: 套接字家族,可以使用AF_UNIX或者AF_INET
type: 套接字类型可以根据是面向连接的TCP还是非连接的UDP分为SOCK_STREAM或SOCK_DGRAM
protocol: 一般不填默认为0.

不同类型的socket与不同类型的底层协议族以及同一协议族中的不同协议栈相关联。现在TCP/IP协议族中的主要socket类型为流套接字(stream sockets)和数据报套接字(datagram sockets)。前者用于实现TCP数据收发,后者用于实现UDP数据收发。

一、TCP数据收发

用于实现TCP数据收发的socket类型为流套接字(stream sockets),可以简略地用socket.socket() 创建套接字。

需要指定通信的地址及端口号,这里的IP地址为本地服务器localhost,也可写成’127.0.0.1’,端口号一般取1024-65535之间的某个值,只要确保客户端和服务器端使用的是同一个端口号即可。

socket对象有不少内建方法用于实现数据收发,以下是比较重要的几个。

服务器端的:
s.bind(),用于绑定地址到套接字,带有的一个参数便是要绑定的地址(host,port)。
s.listen(),开始TCP监听,带有一个参数表示操作系统可以挂起的最大连接数量,至少设置为1,对大部分程序来说设为5即可。
s.accept(),被动接受TCP客户端连接,(阻塞式)等待连接的到来。

客户端的:
s.connect(),用于主动与服务器建立TCP连接,带有的一个参数为服务器daunt地址,形式为(host,port)。

公共的:
s.recv(),接收TCP数据并以字符串形式返回,主要的一个参数bufsize指定要接收的最大数据量,一般设为1024字节。
s.send(),发送TCP数据,将string中的数据发送给连接到的socket。返回值是要发送的字节数量,该数量可能小于string的字节大小。
s.sendall(),完整发送TCP数据。

encode()和decode()用于字符的编码和解码,为了实现编码的统一,在python文件头部添加

# -*- coding: utf-8 -*- 

**完整的代码如下:

注意:因为这份代码的客户端和服务器端都在本地电脑上,所以需要打开两个控制台来分别运行服务器端程序和客户端程序,而且需要先运行服务器端程序。

服务器端:

# -*- coding: utf-8 -*- 
import socket

s = socket.socket()         # 创建 socket 对象
ip_port=('localhost',12345)
s.bind(ip_port)        # 绑定端口
s.listen(5)                 # 等待客户端连接
while True:
    print("Server waiting...")
    conn,addr = s.accept()     # 建立客户端连接
    print("连接地址:",addr)
    #print(c,addr)
    client_data=conn.recv(1024)
    print(client_data.decode())
    conn.send(str("This message came from server:").encode())
    conn.close()                # 关闭连接

客户端:

# -*- coding: utf-8 -*- 
import socket

s = socket.socket()         # 创建 socket 对象
ip_port=('127.0.0.1',12345)      # 设置端口号
s.connect(ip_port)
message=input("Send:")
s.sendall(("This message came from client:"+message).encode())
print("Client waiting...")
reply=s.recv(1024)
print(reply.decode())
s.close()

二、UDP数据收发

UDP的数据收发大部分与TCP的类似,主要的区别有:
socket的创建声明不同,UDP套接字的类型需要声明为SOCK_DGRAM。
一般UDP的socket的创建声明如下:

s= socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

除了上面提到的几个socket对象的内建函数外,还有s.recvfrom()和s.sendto(),分别用于UDP数据的接收和发送。
s.recvfrom(),接收UDP数据,与recv()类似,但返回值是(data,address)。其中data是包含接收数据的字符串,address是发送数据的套接字地址。
s.sendto(),发送UDP数据,将数据发送到套接字,参数为(data,address),其中data是要发送的字符串,address是接收方的套接字地址。

完整代码如下:
服务器端:

# -*- coding: utf-8 -*- 
import socket

s= socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
ip_port=('127.0.0.1',12345)
s.bind(ip_port)
while True:
    print('Server waiting...')   
    client_data, client_addr = s.recvfrom(1024)
    print(client_data.decode())
    s.sendto(str("This message came form server:").encode(), client_addr)

客户端:

# -*- coding: utf-8 -*- 
import socket
 
s= socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_addr = ("127.0.0.1", 12345)
while True:
    message = input("Send:")
    s.sendto(("This message came from client:"+message).encode(), server_addr)
    print("Client waiting...")
    reply, addr = s.recvfrom(1024)
    print(reply.decode())

参考博文:
计算机网络实验二:网络基础编程实验
Python 网络编程

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值