第十二章-网络编程
1 TCP/IP
IP协议赋值吧数据从一台计算机通过网络发送到另一台计算机. 数据是被分割成一个个小块, 然后通过IP包发送出去的. 其中如何在负载的网络链路中传送的是通过路由器进行转发达到最终的目的地
TCP协议是建立在IP协议之上的, TCP协议负责在两台计算机之间建立可靠连接, 而且保证数据包按照顺序到达, 主要是依靠握手协议和对数据包进行编号, 确保数据被对方收到
应用成的HTTP和SMTP等协议都是基于TCP协议的
IP包的组成: 源IP地址, 目的IP地址, 源端口, 目的端口, 数据部分
2 TCP编程
套接字(socket)一般是指 IP+端口
表示打开了一个网络连接
在TCP中, 主动发起连接的叫做客户端, 被动相应的叫做服务器
1) 客户端的使用方法
创建socket对象
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
其中socket.AF_INET表示指定IPv4的协议, 如果使用IPv6的协议应该使用socket.AF_INET6
socket.SOCK_STREAM表示指定使用面向流的TCP协议
客户端连接服务器
client.connect(("127.0.0.1", 8080))
其中的套接字内容是一个元组形式, 第一个元素是IP地址或者域名, 第二个元素是端口号
客户端发送内容
message = input(">> ")
if not message:
continue
if message == "q":
break
client.send(message.encode("utf8"))
客户端使用send方法发送数据, 注意的是, 发送的内容一定是bytes类型的数据
客户端接受数据
buffer = []
while True:
d = client.recv(1024)
if d:
buffer.append(d)
else:
break
data = ''.join(buffer).decode("utf8")
客户端使用recv()方法来获取服务器发送的数据, 其中设置1024表示最多可以接受1024个字节. 服务器发送过来的数据也是bytes类型的数据
关闭客户端
client.close()
2) 服务器的使用方法
创建一个套接字对象并绑定监听的IP地址和端口
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(("127.0.0.1", 8080))
server.listen(5)
其中可以使用0.0.0.0绑定到所有的网络地址, 可以使用127.0.0.1绑定到本机IP地址
其中端口号是0~65535, 其中0~1024是系统的端口号, 绑定系统端口号需要管理员权限
其中listen()方法表示监听, 数字5表示缓存池的大小(等待链接的最大数量)
接受请求并处理内容
while True:
conn, addr = server.accept()
while True:
data = conn.recv(1024)
if not data:
break
try:
res = subprocess.Popen(data.decode("utf8"), shell=True, stdout=subprocess.PIPE)
res = res.stdout.read()
except:
res = "输入的命令有误".encode("gbk")
conn.send(res)
conn.close()
关闭服务器
server.close()
3 UDP编程
UDP是面向无连接的协议
使用UDP只需要知道目的IP和端口, 就可以发送内容, 不需要链接, 也不管是否能够送达
服务器的程序编写
import socket
server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server.bind(('127.0.0.1', 8989))
while True:
data, addr = server.recvfrom(1024)
print(data.decode("utf8"))
server.sendto("客户端你好!".encode("utf8"), addr)
客户端的编写
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
dateList = ["你好", "北京", "我来了!"]
for data in [i.encode("utf-8") for i in dateList]:
client.sendto(data, ('127.0.0.1', 8989))
print(client.recv(1024).decode('utf-8'))
client.close()
总的来说:
UDP在创建的时候是用的是socket.SOCK_DGRAM而不是socket.SOCK_STREAM
服务端使用只需要绑定, 不需要监听, 也不需要接受
客户端使用不需要连接, 直接就能发送和接受