目录
- udp连接
- TCP连接
- 练习实战,文件下载服务器
直入主题
udp连接
这个连接没有明确的服务端与客户端的区别,事实上一个用户既可以是服务端也可以是客户端.在python中使用socket来完成网络编程.
具体代码如下:
客户端
#socket.AF_INET 是建立连接 socket.SOCK_DGRAM 是使用UDP链接
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
id = socket.gethostbyname(socket.gethostname()).split(":")[0]
s.sendto('hello'.encode('utf'),(id,8088))
s.close()
print("发送成功!!!!")
服务端
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
id = socket.gethostbyname(socket.gethostname()).split(":")[0]
s.bind((id,8088))
print('准备接收中')
data=s.recvfrom(1024)
print("%s"%(data[0].decode('utf')))
下面是解释:
gethostbyname()方法可以获取到当前主机的IP地址(局域网内)
recvfrom()是接受信息,这个是从客户端接受的同时这个一个堵塞的方法
该方法返回两个值,一个是二进制数据,另一个是发送者的IP和端口
bind()则是绑定IP和端口,在接受数据的时候需要使用
TCP连接
tcp和udp不同的区别是,tcp需要先进行对服务端的连接,这样做的好处是可以保证数据传输的安全性.udp是只发送而不保证连接的,这样一来就容易出现问题.
下面是一段示例:
客户端:
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
id = socket.gethostbyname(socket.gethostname()).split(":")[0]
s.connect((id,8089))
s.send('hello'.encode('utf8'))
print("数据发送完成")
tes=s.recv(1024)
print(tes.decode('utf8'))
s.close()
服务端
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
id = socket.gethostbyname(socket.gethostname()).split(":")[0]
s.bind((id,8089))
print("TCP服务器开启")
s.listen(128)
data,ip_where=s.accept()
print(data.recv(1024).decode('utf8'))
data.send('world'.encode('utf8'))
说明:
在服务端我们使用accept()接收数据
其中返回两个值,一个是发送者的socket,这就意味着我们可以直接使用这个接受发送者的数据并且向他发送数据,而第二个则是发送者的IP和端口
lsten()这是服务器最大超出压力的连接者数量,这里设置128意味着最多能够超负荷128个连接.
练习实战,文件下载服务器
考虑到下载的安全性,毫无意外我们使用tcp连进行连接
客户端
import socket
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
id = socket.gethostbyname(socket.gethostname()).split(":")[0]
s.connect((id,8089))
filename = str(input("输入您要下载的音乐:"))
s.send(filename.encode('utf-8'))
data = s.recv(1024)
try:
data.decode("utf-8")
print("文件不存在")
except :
#由于是在同一台电脑上为了做出区别下载的文件名字前面会加"下载的"
with open("下载的"+filename,'wb') as file:
file.write(data)
while True:
data=s.recv(1024)
if data:
file.write(data)
else:
print("下载完成")
break
服务端:
import socket
import os
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
id = socket.gethostbyname(socket.gethostname()).split(":")[0]
s.bind((id,8089))
s.listen(128)
print("服务器启动")
client = s.accept()[0]
filename = client.recv(1024).decode("utf-8")
if os.path.isfile(filename):
with open(filename,'rb') as file:
content = file.read()
client.send(content)
print("文件发送完成")
else:
client.send("文件不存在".encode('utf-8'))
速度很快,几乎瞬间完成