当前位置:   article > 正文

python网络编程

python网络编程

什么是 Socket?

Socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯。

socket()函数

Python 中,我们用 socket() 函数来创建套接字,语法格式如下:

socket.socket([family[, type[, proto]]])

参数

  • family: 套接字家族可以是 AF_UNIX (文件类型的套接字)或者 AF_INET(网络型套接字ipv4)还有AF_INET6(用于 IPv6 网络通信)
  • type: 套接字类型可以根据是面向连接的还是非连接分为SOCK_STREAM(UDP方式)SOCK_DGRAM(TCP方式)
  • proto: 一般不填默认为0.

什么是UDP

UDP(User Datagram Protocol,用户数据报协议)是一种无连接的协议,用于在IP主机和应用程序之间发送数据报。与TCP(Transmission Control Protocol,传输控制协议)不同,UDP不提供数据报的排序、重传或确认机制,因此被称为不可靠的协议。

UDP的主要特点如下:

  1. 无连接:UDP不建立连接,可以直接发送数据报,不需要像TCP那样进行三次握手建立连接。
  2. 不可靠:UDP不保证数据报的顺序、重传或确认,因此可能会出现数据丢失、乱序或重复的情况。
  3. 面向报文:UDP将应用程序发送的数据分成多个数据报,每个数据报独立发送,并在接收端重新组合成原始数据。
  4. 速度快:由于UDP没有确认机制和重传机制,因此它的传输速度通常比TCP更快。
  5. 头部开销小:UDP的数据报头部开销只有8个字节,相比之下TCP的头部开销为20个字节。

使用UDP实现一个聊天器系统

 主要功能:

1、向指定主机和端口发送消息

2、指定接收消息的端口并接收消息、

3、使用多线程方法一直接收消息

主要方法:

1、创建UDP套接字

udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

2、绑定接收端口

udp_socket.bind(("", 8888))

3、发送消息

因为计算机间的通信是二进制的,需要使用encode()方法将发送的数据转为二进制

udp_socket.sendto(send_str.encode(), (ip_str, port))

4、接收消息

recvfrom的返回值是一个元组,接收到的消息分为两部分,一部分是消息内容,一部分是发送方的ip和端口。同样的接收到的消息需要使用decode()方法解码

data = udp_socket.recvfrom(1024)
  1. import socket
  2. import threading
  3. """UDP聊天器"""
  4. def Socket_Sento(udp_socket):
  5. ip_str = input("请输入对方的ip地址:")
  6. port = int(input("请输入对方的端口号:"))
  7. send_str = input("请输入要发送的内容:")
  8. udp_socket.sendto(send_str.encode(), (ip_str, port))
  9. def Socket_Recvfrom(udp_socket):
  10. while True:
  11. data = udp_socket.recvfrom(1024)
  12. print("来自主机:%s:%d发来的消息:%s\n" % (data[1][0], data[1][1], data[0].decode("gbk")))
  13. def main():
  14. udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  15. udp_socket.bind(("", 8888))
  16. t1 = threading.Thread(target=Socket_Recvfrom, args=(udp_socket,), daemon=True)
  17. t1.start()
  18. while True:
  19. print("\n\n***************************")
  20. print("****** 1、发送信息 *******")
  21. print("****** 2、退出系统 *******")
  22. print("***************************")
  23. num = input("请选择功能序号\n")
  24. if num == "1":
  25. Socket_Sento(udp_socket)
  26. elif num == "2":
  27. break
  28. else:
  29. print("输入错误")
  30. udp_socket.close()
  31. if __name__ == "__main__":
  32. main()

什么是TCP

TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。

使用TCP时与UDP不同,需要先建立连接

tcp_client_socket.connect(("192.168.56.1",8080))

使用TCP模拟客户端

  1. import socket
  2. # 创建套接字
  3. tcp_client_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
  4. # 建立连接
  5. tcp_client_socket.connect(("192.168.56.1",8080))
  6. # 发送数据
  7. tcp_client_socket.send("约吗".encode())
  8. # 接收数据
  9. print(tcp_client_socket.recv(1024).decode("gbk"))
  10. tcp_client_socket.close()

使用TCP模拟服务器端

当TCP作为服务端的时候需要设置地址重用、绑定端口、设置监听

tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
tcp_server_socket.bind(("", 8080))
tcp_server_socket.listen(128)
  1. import socket
  2. import threading
  3. """多线程TCP服务框架"""
  4. def recv_msg(new_socket, client_port):
  5. while True:
  6. recv_data = new_socket.recv(1024)
  7. if recv_data:
  8. print("来自[%s]发送的数据:%s" % (client_port, recv_data.decode("gbk")))
  9. else:
  10. print("客户端已断开连接")
  11. break
  12. tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  13. # 设置地址重用
  14. tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
  15. # 绑定端口
  16. tcp_server_socket.bind(("", 8080))
  17. # 设置监听
  18. tcp_server_socket.listen(128)
  19. # 循环实现多个客户端连接
  20. while True:
  21. new_socket, client_port = tcp_server_socket.accept()
  22. print("与%s连接成功" % str(client_port))
  23. recv_thread = threading.Thread(target=recv_msg, args=(new_socket, client_port), daemon=True)
  24. recv_thread.start()
  25. # tcp_server_socket.close()

使用TCP模拟浏览器发送请求并接收服务器的响应数据

浏览器的请求分为get请求和post请求

get请求的请求协议包含请求行、请求头、请求空行

post请求的请求协议包含请求行、请求头、请求空行、请求内容

  1. import socket
  2. # 创建套接字
  3. tcp_client_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
  4. # 建立连接
  5. tcp_client_socket.connect(("127.0.0.1",8080))
  6. # 拼接请求协议
  7. # 请求行
  8. request_line="GET / HTTP/1.1\r\n"
  9. #请求头
  10. request_header="Host:www.baidu.com\r\n"
  11. #请求空行
  12. requset_blank="\r\n"
  13. request_data=request_line+request_header+requset_blank
  14. #发送请求协议
  15. tcp_client_socket.send(request_data.encode())
  16. #接收服务器响应内容
  17. respon_data=tcp_client_socket.recv(4096).decode()
  18. html_data=respon_data[respon_data.find("\r\n\r\n")+4:]
  19. print(html_data)
  20. # 保存内容
  21. with open("D:\\PycharmProjects\\TextProject\\Text_TCP_Web\\index.html","w") as file:
  22. file.write(html_data)
  23. #关闭连接
  24. tcp_client_socket.close()

使用TCP设计服务器返回固定数据

首先需要解码请求协议,将接收到的请求解码拆分得到要请求的内容

然后创建响应协议:响应行、响应头、响应空行、响应主体,最后拼接发送给请求端

  1. import socket
  2. def request_headler(new_client_socket, ip_port):
  3. request_data = new_client_socket.recv(1024).decode()
  4. # print(request_data)
  5. # 接收客户端浏览器发送的请求
  6. # 判断协议是否为空
  7. if not request_data:
  8. print("%s用户已下线" % str(ip_port))
  9. new_client_socket.close()
  10. return
  11. # 根据客户端浏览器请求的资源路径,返回请求资源
  12. # 把请求协议解码,得到请求报文的字符串
  13. # 得到请求行
  14. # 查找第一个\r\n出现得位置
  15. # 使用切片获取请求行
  16. requst_line = request_data[0:request_data.find("\r\n")]
  17. # 按空格分割创建数组
  18. requst_line_list = requst_line.split(" ")
  19. # 获取到指定文件
  20. file_path = requst_line_list[1]
  21. # 如果没有指定访问的文件就返回默认首页
  22. if file_path == "/":
  23. file_path = "index.html"
  24. print("[%s]用户请求了%s资源" % (str(ip_port), file_path))
  25. # 拼接响应的报文
  26. # 响应行
  27. respon_line = "HTTP/1.1 200 OK\r\n"
  28. # 响应头
  29. respon_header = "Server:Python\r\n"
  30. # 响应空行
  31. respon_blank = "\r\n"
  32. # 响应主体
  33. # respon_body = "Hello Wolrd"
  34. # 返回指定页面
  35. try:
  36. with open("..\\static\\" + file_path, "rb") as file:
  37. respon_body = file.read()
  38. except Exception as e:
  39. respon_line = "HTTP/1.1 404 Not Found\r\r"
  40. respon_body = "Error! (%s)" % e
  41. respon_body = respon_body.encode()
  42. # 发送响应报文
  43. respon_data = (respon_line + respon_header + respon_blank).encode() + respon_body
  44. new_client_socket.send(respon_data)
  45. def main():
  46. # 创建套接字
  47. tcp_sderver_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  48. # 设置端口重用、
  49. tcp_sderver_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
  50. # 绑定端口
  51. tcp_sderver_socket.bind(("", 8080))
  52. # 设置监听,让套接字由主动变为被动接收
  53. tcp_sderver_socket.listen(128)
  54. # 接受客户端的请求 定义函数request_handler()
  55. while True:
  56. new_client_socket, ip_port = tcp_sderver_socket.accept()
  57. print("新用户%s来了" % str(ip_port))
  58. request_headler(new_client_socket, ip_port)
  59. # 关闭操作
  60. tcp_sderver_socket.close()
  61. if __name__ == "__main__":
  62. main()

使用TCP模拟客户端从服务器端下载文件功能

客户端代码

  1. import socket
  2. clinent_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
  3. clinent_socket.connect(("192.168.56.1",8080))
  4. file_name=input("请输入要下载的文件名:")
  5. clinent_socket.send(file_name.encode())
  6. with open("C:\\Users\\Administrator\\Desktop\\copy\\"+file_name, "wb") as source_file:
  7. while True:
  8. file_data = clinent_socket.recv(1024)
  9. if file_data:
  10. source_file.write(file_data)
  11. else:
  12. break
  13. clinent_socket.close()

服务端代码

  1. import socket
  2. server_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
  3. server_socket.bind(("",8080))
  4. server_socket.listen(128)
  5. while True:
  6. new_server_socket,clinet_port=server_socket.accept()
  7. print("客户端[%s]已连接"%str(clinet_port))
  8. clinet_data=new_server_socket.recv(1024)
  9. try:
  10. with open("C:\\Users\\Administrator\\Desktop\\"+clinet_data.decode(),"rb") as server_file:
  11. while True:
  12. file_date=server_file.read(1024)
  13. if file_date:
  14. new_server_socket.send(file_date)
  15. else:
  16. print("文件传输完成")
  17. break
  18. except Exception as e:
  19. print("文件%s传输失败"%clinet_data.decode())
  20. new_server_socket.close()
  21. server_socket.close()

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/45903?site
推荐阅读
相关标签
  

闽ICP备14008679号