Python-socket模块网络编程基本使用(TCP和UDP协议)

目录

一、socket模块通信简述

二、TCP和UDP的大致区别

三、常用参数

四、常用方法

4.1 TCP协议常用方法

4.2 UDP协议常用方法

五、简单程序实例

5.1 TCP协议

5.2 UDP协议


一、socket模块通信简述

本次主要是大致说明socket模块可以使用的两个通信协议TCP和UDP。注意网络通信是多端的,不可能就一个程序来完成,在不同的端程序也会有所不同。我们所说的端一般为服务器端客户端。服务器端和客户端的程序是不同的。并且我们是要先打开服务器,再打开客户端开始通信。

TCP协议服务器端建立了连接,所以要关闭这个连接。UDP协议服务器什么都没做。也就不需要服务器关闭什么。

当然你要是想关服务器的话,那也可以给服务器给关掉。

1.1 TCP协议程序结构流程图图(以下左边是服务器端,右边是客户端)

 1.2 UDP协议程序结构流程图

二、TCP和UDP的大致区别

TCP相对来说复杂一些,TCP协议服务器会创建一个新的连接socker对象来与客户端互相通信。而UDP就不会。所以在后面也可以看出,TCP一旦建立连接后,发送数据就不再需要地址直接send(data)即可,但是UDP通信是没有建立连接,所以发送数据需要服务器的地址,它使用的方法为sendto(data, address)。这就是它们的主要区别。

TCP发送数据前要先建立连接(connect);UDP发送数据前不建立连接,但发送数据是要传入一个参数为服务器的地址(address)

注意:

  1. 它发送的数据必须是字节序列对象,类似与我们的图片(jpg文件等)文件。图片其本质上就是一连串字节序列对象,每一个像素点为8位二进制字节序列(灰度图像,彩色图像是3通道,所以每一个像素点为24位二进制字节序列)。
  2. 上面以及下文所说的地址都是(ip地址, 端口号),是ip地址和端口号组成的二个元素的元组。

 

三、常用参数

socket.AF_INET:表示使用IPv4地址

socket.SOCK_STREAM:表示使用TCP通信协议,用于创建TCP Socket对象的参数

socket.SOCK_DGRAM:表示使用UDP通信协议,用于创建UDP Socket对象的参数

address参数:是ip地址和端口号的二元组。即:(ip地址,端口号)

四、常用方法

网络通信分为服务器端和客户端。

两个使用的函数(socket类的方法)也有一些不同。

4.1 TCP协议常用方法

TCP协议通信需要服务器监听端口,并阻塞端口,等待客户端连接。

创建TCP Socket对象

<模块名.类名>

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

socket类对象有很多方法。

以下为:

<类对象.方法>

服务器端一般用:

socket.bind(address):绑定地址和端口

socke.listen(backlog):监听端口,backlog是最大连接数,即该端口最多能连接的客户端数。

socket.accept():使用阻塞方法,等待客户端连接,并返回(coon,address)二元组对象。

其中coon是连接用的socket类对象, address为客户端地址(形式见上)

客户端一般用:

socket.connect(address):连接服务器socket,address是服务器的ip地址和端口号

服务器端和客户端共同使用的方法有:

socket.recv(buffsize):接收TCP Socket数据,该方法返回字节序列对象(我们打的字符串是Unicode编码对象,应先用字符串类的encode()方法,将其变为字节序列编码对象,再发送)。buffsize是一次最大接收字节数。

socket.send(bytes):发送TCP Socket数据,将字节序列对象(数据)发送到远程socket,返回成功发送的字节数。如果发送的数据量很大,需要多次调用该方法发送数据。

socket.sendall(bytes):和send()功能一样,如果发送成功返回None,发送失败则抛出异常。该方法会一次将数据全部发送完。

socket.close():关闭Socket。

4.2 UDP协议常用方法

服务器使用:

只需要使用TCP协议中的的bind()方法。不需要listen()和accept()方法。

因为UDP通信不需要像TCP一样监听端口,建立连接。

客户端使用:

socket.recvfrom(buffsize):接收UDP Socket数据,该方法返回(data,address)二元组对象,data是字节序列对象,address是发送数据的远程Socket地址,

参数buffsize表示一次接收的最大字节数。

socket.sendto(bytes, address):发送UDP Socket数据。将bytes数据发送到地址为adress的远程Socket,返回成功发送的字节数。

socket.close():关闭Socket。

五、简单程序实例

5.1 TCP协议

5.1.1 服务器端

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定自己的ip地址和端口号
s.bind(('0.0.0.0', 8888))  # 0.0.0.0表示可以监听任何网段
print(socket.gethostname())     # 返回主机名字
# 监听端口
s.listen()
print('服务器启动...')

# 等待客户端连接,用阻塞方法s.accept
coon, address = s.accept()

# 客户端连接成功
print(address)

# 接受客户端数据
data = coon.recv(1024)
print('从客户端接收消息:{0}'.format(data.decode()))# 接受的消息需解码为字符串

# 客户端发送数据
coon.send('你好'.encode())    # 发送的数据需要编码为字节流
# 释放服务器端资源
coon.close()
print('服务器端已释放资源!')

s.close()

5.1.2 客户端

import socket

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

#连接服务器
s.connect(('127.0.0.1', 8888))
#给服务器发送消息
s.send(b'Hello')

#从服务器接受消息
data = s.recv(1024)
print('从服务器端接收消息:{0}'.format(data.decode()))

s.close()
print('客户端以释放资源!')

5.2 UDP协议

5.2.1 服务器端

import socket

#使用IPv4地址类型,使用UDP协议
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

s.settimeout(10)    # 设置超时时间,如果服务器一段时间为与客户端通信,则主动关闭服务器端


s.bind(('',8888))
print('服务器启动......')

data, client_address = s.recvfrom(1024)
print('从客户端接收消息:{0}'.format(data.decode()))


s.sendto('你好'.encode(), client_address)

s.close()

5.2.2 客户端

import socket

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

#服务器地址
server_address = ('127.0.0.1', 8888)

#给服务器发送数据
s.sendto(b'Hello', server_address)

#从服务器端接收数据
data,_ = s.recvfrom(1024)
print('从服务端接收消息:{0}'.format(data.decode()))