第八章 socket网络编程(3):什么是socket(套接字)

TCP/UDP协议是非常复杂的,我们编程的时候不可能都深入了解,所以这时候就有大牛们为网络编程的程序猿准备了封装好的模块, 程序猿们只要调用接口就可以实现网络通信,不需要深入了解协议的原理。

Socket抽象层
+ 在传输层和应用层之间:作用是让应用层只要跟Socket抽象层交互就可以了
+ 把传输层以下的功能(包括传输层)全都封装好了,留出接口给程序猿们使用:应用层直接调用Socket抽象层的接口就可以了

有了Socket抽象层,我们只需要用Socket的接口就可以实现网络编程了。

Socket有两个家族(family):
+ 基于文件类型:AF_UNIX
+ 基于网络类型:AF_INET

基于TCP工作的Socket的工作流程(简单的范例软件):

server.py

import socket

#1 买手机
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # AF_INET是网络类型家族(基于网络通信),stream是流的意思,即TCP协议(流式协议)
# print(phone)

#2 绑定手机卡(绑定IP和端口)
phone.bind(('127.0.0.1',8080))  # 以元组的形式传入 服务端IP 和 接收端口
# IP需要设成服务器端的IP地址这里我们服务器和客户端都在本地,用本地回环IP:127.0.0.1
# 端口0-65535范围,其中0-1024是操作系统用的,其他的可以给我们的软件选用
# 注意:在重复运行软件的时候可能会报错,说端口已被占用。你可以换个端口,这时候客户端访问的端口也得换

#3 监听(设置最大可挂起数)
phone.listen(5)  # backlog:设置为5,最大挂起的连接数。类似电话占线,最多可以让5个人等待。这个值一般应该放在配置文件中

#4 等待呼叫(接受连接)
print('starting...')  
conn, client_addr = phone.accept()  # 服务器端会在这里等待客户端访问,返回的是2各元素的元组,所以我们分别赋值给conn和client_addr
# 被连接了会返回一个由 (连接对象,客户端IP&端口)组成的元组
# (<socket.socket fd=220, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 1912)>, ('127.0.0.1', 1912))

#5 收,发消息(传数据)
# 使用连接对象来收,发消息
data = conn.recv(1024)  # recv是收,收1024字节:代表接受数据的最大1024bytes
print('客户端的数据',data)

conn.send(data.upper())  # 送回客户端数据

#6 挂电话(释放连接对象)
conn.close()  # 断开和此客户端的连接

#7 关机(关闭服务)
phone.close()  # 停止服务端的服务

# 服务端有2种套接字:phone,conn
# phone作用:绑定,监听,接受连接
# conn作用:收,发消息

client.py

import socket

#1 买手机
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # AF_INET是网络类型家族(基于网络通信),stream是流的意思,即TCP协议(流式协议)
 
# 客户端不需要绑定IP和端口

#2 拨号(发送请求)
phone.connect(('127.0.0.1',8080))  # 连接服务器的IP和端口

#3 发,收消息
phone.send('hello'.encode('utf-8'))  # 以前我们讲过,网络传输需要用bytes类型来传输
data = phone.recv(1024)
print(data)

#4 关闭
phone.close()

# 客户端只有1种套接字:发,收消息

猜你喜欢

转载自www.cnblogs.com/py-xiaoqiang/p/11298968.html