网络编程
通信协议
因为大标题是‘自学Python’所以本章主要介绍Python的Socket函数,具体的网络通信基础将由另一套独立的网络通信具体章节介绍。参考资料来自《图解TCP/IP》【日】竹下隆史、村山宫保、荒井透、苅田幸雄 著。预计一周读完。大概在十二月中旬以后开始正式编写这一系列博客。
Socket
Socket套接字,可以吧它暂时理解成是语言对协议的封装接口,把Socket当做正常的类进行介绍。用Python中的socket的socket()函数进行初始化就可以。
例:
s = socket.socket(AddressFamily,Type)
‘’‘
函数socket()创建一个socket,返回该socket的描述符。
AddressFamily :可以选择AF_INET(用于Internet进程间通信)或者AF_UNIX(用于同一台机器的进程间通信,不常用一般都用消息对列)
Type:套接字类型 可以选择 SOCK_STREAM(流式套接字,TCP协议)SOCK_DGRAM(数据报套接字,UDP协议)
’‘’
#例1:TCP套接字
tcpSock = socket.socket(AF_INET,SOCK_STREAM)
#例2:UDP套接字
UdpSock = socket.socket(AF_INET,SOCK_DGRAM)
socket的内置方法和说明
方法 | 说明 |
---|---|
bind() | 绑定地址(host,port)到到套接字,在AF_INET下,以元组(host,port)形式表示地址 |
listen() | 开始TCP监听。backlog指定在拒绝链接之前,操作系统可以挂起的最大链接数量。该值至少为一大部分应用程序设置为5就可以 |
accept() | 被动接受TCP客户端链接(阻塞式),等待连接的到来 |
connect() | 主动初始化TCP服务器连接,一般address的格式为元组(hostname,prot),A如果连接出错返回socket.error错误 |
recv() | 接受TCP数据,数据将以字符串的形式返回,bufsize指定要接收的最大数据量提供有关消息的其他信息,通常可以忽略 |
send() | 发送TCP数据,将string中的数据发到连接的套接字。返回的是要发送的字节数量,该数量可能小于string的字节大小 |
sendall() | 完整发送TCP数据,将完整的发送TCP数据,将string中的数据发到连接的套接字。但是在返回之前会尝试发送所有数据,成功返回None,失败则抛出异常 |
recvfrom() | 接受UDP数据与recv()类似,但是返回值是(data,address)。其中data是是包含数据的字符串,address是发送数据的套接字地址 |
sendto() | 发送UDP数据,将数据发送到套接字,address是形式为(ipaddr,port)的元组指定远程地址,返回值是发送的字节数 |
close() | 关闭套接字 |
TCP编程
创建TCP服务器
步骤:
1、使用socket()创建一个套接字
2、使用bind()绑定IP和port
3、使用listen()使套接字变为可被动连接
4、使用accept()等待客户端的连接
5、使用recv/send()接受发送数据
例:向本地浏览器发送“Hello 花猪”
# -*- coding:utf-8 -*-
import socket #导入socket模块
host = "170.0.0.1" #主机IP地址
port = 8080 #端口号
wed = socket.socket() #创建套接字
wed.bind((host,port)) #绑定IP和端口号
wed.listen(5) #设置可被动连接和最大连接数
print("等待客户端进行连接")
#开启死循环
while(True):
coon,addr = web.accept() #建立客户端连接
data = conn.recv(1024) #获取客户端请求数据
print(data) #打印接受到的数据
coon.sendall(b”HTTP/1.1 200 OK\r\n\r\nHellon 花猪“) #向客户端发送数据
conn.close() #关闭连接
创建客户端
上个例子是做的是以浏览器做客户端的方式,下面自己写一个客户端连接到上面的例子中的服务器
例:
# -*- coding:utf-8 -*-
import socket #导入socket模块
host = "170.0.0.1" #主机IP地址
port = 8080 #端口号
myclient = socket.socket() #创建套接字
myclient.connect((host,port)) #初始化服务器连接
send_data = input("输入要发送的数据:") #输入数据
myclient.send(send_data.encode()) #向服务器发送数据
recv_data = myclient.recv(1024).decode() #接受服务器数据
print("接受到的数据:",recv_data) #输出数据
TCP通信模型
由于并不会在CSDN插入流程图只能再来个具体的例子体会一下TCP通信
(简单的聊天程序)
例:
创建server.py文件作为服务器程序
# -*- coding:utf-8 -*-
import socket #导入socket模块
host = socket.gethostname() #主机IP地址
port = 123454 #端口号
mys = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #创建套接字
mys.bind((host,port)) #绑定IP和端口号
mys.listen(1) #设置可被动连接和最大连接数
print("等待客户端进行连接")
myc,addr = mys.accept() #建立客户端连接
print("客户端已连接")
#开启死循环
while recv_data != "胖花猪":
if recv_data:
print("接收到的内容" + recv_data
send_data = input("输入要发送的数据:") #输入数据
myc.send(send_data.encode()) #向客户端发送数据
if send_data == “丑黑蛇”:
break
recv_data = myc.recv(1024).decode() #接受客户端数据
mys.close()
myc.close()
创建client.py文件作为服务器程序
# -*- coding:utf-8 -*-
import socket #导入socket模块
host = socket.gethostname() #主机IP地址
port = 123454 #端口号
myc = socket.socket() #创建套接字
myc.connect((host,port)) #连接服务器IP和端口号
print("已连接")
#开启死循环
while recv_data != "丑黑蛇":
if recv_data:
print("接收到的内容" + recv_data
send_data = input("输入要发送的数据:") #输入数据
myc.send(send_data.encode()) #发送数据
if send_data == “胖花猪”:
break
recv_data = myc.recv(1024).decode() #接受数据
myc.close()
UDP编程
(例子为摄氏温度和华氏温度的转换)
创建UDP服务器
例:
创建server.py文件作为服务器程序
# -*- coding:utf-8 -*-
import socket #导入socket模块
mys = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) #创建套接字
mys.bind(("127.0.0.1",8080)) #绑定IP和端口号
data, addr = myc.recvfrom(1024) #接受客户端数据
data = float(data) * 1.8 + 32
send_data = "转化后的温度(单位华氏温度):" + str(data)
mys.sendto(send_data.encode(),addr) #向客户端发送数据
myc.close()
创建client.py文件作为服务器程序
# -*- coding:utf-8 -*-
import socket #导入socket模块
myc = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) #创建套接字
data = input(输入摄氏温度:)
mys.sendto(data.encode(),(127.0.0.1)) #向客户端发送数据
print("输出华氏温度:%s",%myc.recv(1024).decode())
myc.close()
总结
TCP的核心是创建连接,以确保安全可靠的特性。类似打电话,两个人必须都有手机,必须都都电话卡,而且要知道对方的电话号,对方的手机也在身边。
UDP的通信模式中在通信开始不需要建立连接,只需要发送数据即可。类似于写信,只需要地址就好,但是信能不能收到就不一定了,佛系随缘