说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢你们!python
目录编程
一丶项目介绍python3.x
二丶服务器Server服务器
五丶测试客户端向服务器下载文件socket
1.叙述tcp
生活中你们都使用过迅雷吧,用户在客户端上使用迅雷从服务器上download一个文件到客户端,今天博主就是使用TCP网络搭建一个客户端client链接服务器server,从服务器server上下载所想要下载的文件到客户端client上编程语言
2.项目环境函数
操做系统:Windows7
IDE:PyCharm2017
编程语言:python3.x
测试工具:网络调试工具3.x
1.在PyCharm中建立file_download_tcpServer.py和file_download_tcpClient.py文件用于实现tcp服务器客户端
2.首先在file_download_tcpServer.py中进行代码逻辑编写
tcp_server_socket = socket(AF_INET, SOCK_STREAM)
tcp_server_socket.bind(('', 8888))
tcp_server_socket.listen(128)
client_socket, clientAddr = tcp_server_socket.accept()
print("用户%s 已链接"% str(clientAddr))
recv_data = client_socket.recv(1024) # 接收1024个字节 file_name = recv_data.decode("utf-8") print("对方请求下载的文件名为:%s" % file_name)
try: with open(filename, "rb") as f: file_content = f.read() except Exception as e: print("获取文件内容出错:", e) if file_content: client_socket.send(file_content) # 关闭该套接字 client_socket.close()
tcp_server_socket.close()
3.封装(解耦)代码,博主之因此这样作,是为了让你们了解一个正确开发过程,提升代码复用性
从上面代码能够看出耦合性比较严重,看着杂乱无章比较费劲,因此须要对代码进行解耦操做,下降代码耦合性,获取客户端下载文件内容能够封装到一个方法里(get_file_content),而tcp 服务器建立套接字以及关闭均可以封装到main方法里面,以下所示
def get_file_content(filename): """获取文件内容""" try: with open(filename, "rb") as f: content = f.read() return content except Exception as e: print("获取文件内容出错:", e) def main(): # 建立socket tcp_server_socket = socket(AF_INET, SOCK_STREAM) # 绑定本地信息 tcp_server_socket.bind(('', 8888)) # 使用listen将主动套接字变为被动套接字 tcp_server_socket.listen(128) while True: # 等待客户端的连接,即为这个客户端发送文件 client_socket, clientAddr = tcp_server_socket.accept() print("用户%s 已链接"% str(clientAddr)) # 接收客户端发送过来的数据获取客户要下载的文件名 recv_data = client_socket.recv(1024) # 接收1024个字节 file_name = recv_data.decode("utf-8") print("对方请求下载的文件名为:%s" % file_name) file_content = get_file_content(file_name) # 发送文件的数据给客户端,获取文件内容使用rb二进制,因此这里不须要进行encode编码操做 if file_content: client_socket.send(file_content) # 关闭客户端套接字 client_socket.close() # 关闭服务器监听套接字 tcp_server_socket.close() if __name__ == "__main__": main()
4. 指定服务器运行方式为python3 xxx.py 8888,将服务器绑定端口号传入到代码中
import sys print(len(sys.argv))
def main(): import sys if len(sys.argv) != 2: print("请按照以下方式运行:python3 xxx.py 8888") return else: # 运行方式为python3 xxx.py 8888 port = int(sys.argv[1]) # 8888
1.在Terminal终端执行python3 file_download_tcpServer.py 没有传入端口号,出现定义的提示
2.在Terminal终端执行python3 file_download_tcpServer.py 8888即成功运行tcp 服务器并绑定8888端口,终端光标开始闪烁等待客户端的链接
3.打开网络调试助手,选择TCP client客户端,IP地址为本机IP 端口为服务器绑定端口号8888,
4.点击链接成功后,回到pycharm Terminal终端,此时终端显示用户XXXX已链接
5.在网络调试助手中发送demo.py文件名(client发送下载文件名必须存在于服务器端),此时服务器获取客户端发送的下载文件名,获取该文件的内容发送给客户端,表明服务器代码逻辑编写正确
1.在file_download_tcpClient.py中进行代码逻辑编写,相对服务器来讲客户端的代码实现就比较简单,首先定义main主函数用于客户端建立套接字链接目标服务器
tcp_client_socket = socket(AF_INET, SOCK_STREAM)
tcp_client_socket.connect((input("请输入服务器ip:"), int(input("请输入服务器port:"))))
file_name = input("请输入要下载的文件名:") tcp_client_socket.send(file_name.encode("utf-8"))
recv_data = tcp_client_socket.recv(1024)
if recv_data: with open("[接收]"+file_name, "wb") as f: f.write(recv_data)
tcp_client_socket.close()
2.客户端完整代码
from socket import * def main(): # 建立socket套接字 tcp_client_socket = socket(AF_INET, SOCK_STREAM) # 链接目标服务器 tcp_client_socket.connect((input("请输入服务器ip:"), int(input("请输入服务器port:")))) # 输入须要下载的文件名 file_name = input("请输入要下载的文件名:") # 向服务器发送文件下载请求 tcp_client_socket.send(file_name.encode("utf-8")) # 接收服务器发送过来的数据 recv_data = tcp_client_socket.recv(1024) print('接收到的数据为:', recv_data.decode('utf-8')) # 接收数据不为空时,写入到本地客户端, if recv_data: with open("[接收]"+file_name, "wb") as f: f.write(recv_data) # 关闭套接字 tcp_client_socket.close() if __name__ == "__main__": main()
1.首先在Terminal终端上执行python3 file_download_tcpServer.py 8888将服务器运行在8888端口上,此时服务器正等待客户端链接
2.在pycharm上直接run运行 file_download_tcpClient.py客户端
3.在服务器目录下存放一张1.jpg头像图片,进行测试
recv_data = tcp_client_socket.recv(100000)