网络编程(2)

编程入门 行业动态 更新时间:2024-10-28 18:30:34

<a href=https://www.elefans.com/category/jswz/34/1768814.html style=网络编程(2)"/>

网络编程(2)

网络通信方式-TCP

2.1,TCP介绍

  • TCP协议,传输控制协议(英文:Transmission Control Protocol,缩写为TCP)是一种面向连接的,可靠的,基于字节流的传输层通信协议,由IETF的RFC 793定义。
  • TCP通信需要经过创建连接数据传送终止连接三个步骤。
  • TCP通信模型中,在通信开始之前,一定要建立相关的连接,才能发送数据,类似于打电话

  • TCP特点
  1. 面向连接

    通信双方必须先建立连接才能进行数据的传输,双方都必须为该链接分配必要的系统内核资源,以管理连接的状态和连接上的传输。

    双方间的数据传输都可以通过这一个连接进行。

    完成数据交互后,双方必须断开连接,以释放系统资源

    这种连接是一对一的,因此TCP不适用于广播的应用程序,基于广播的应用程序请使用UDP协议

  2. 可靠传输

    1),TCP采用发送应答机制

    TCP发送的每个报文段都必须得到接收方的应答才认为这个TCP报文段传输成功

    2),超时重传

    发送端发出一个报文段之后就启动定时器,如果在定时器时间内没有收到应答就重新发送这个报文段

    TCP为了保证不发生丢包,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收,然后接收端实体对已成功收到的包发回一个相应的确认(ACK);如果发送端实体在合理的返时延(RTT)内未确认,那么对应的数据包就被假设为已丢失将会被进行重传

    3),错误效验

    TCP用一个效验和函数来检验数据是否有错误;在发送和接收时都要计算效验和

    4),流量控制和阻塞管理

    流量控制用来避免主机发送的过快而使接收方来不及完全收下

    TCP与UDP的不同点

    • 面向连接(确认有创建三方交握,创建已创建才作传输)
    • 有序数据传输
    • 重发丢失的数据包
    • 舍弃重复的数据包
    • 无差错的数据传输
    • 阻塞/流量控制

    UDP通信模型

    通信的过程中会被别人截胡或者意外丢失,而且发送方也不知道接收方有没有收到,不安全,类似发信件一样,发信以后不知道对方会不会收到,信在途中会不会丢失

    TCP通信模型

    TCP 通信之前必须建立要相关的连接,才能发送数据,类似打电话,双发一定要有联系才可以发送数据,是确保数据能100%接收,比udp安全,数据完整

2.2,TCP客户端(重要)

一共四步,创建tcp_socket,绑定端口和ip,发送数据,关闭socket

  • 原始版本

     # !/usr/bin/env python# _*_ coding:utf-8 _*_# author:满怀心 2019/7/30 12:00"""# code is far away from bugs with the god animal protectingI love animals. They taste delicious.┏┓      ┏┓┏┛┻━━━┛┻┓┃      ☃      ┃┃  ┳┛  ┗┳  ┃┃      ┻      ┃┗━┓      ┏━┛┃      ┗━━━┓┃  神兽保佑    ┣┓┃ 永无BUG!   ┏┛┗┓┓┏━┳┓┏┛┃┫┫  ┃┫┫┗┻┛  ┗┻┛"""from socket import *def main():# 1. 创建tcp套接字,注意type类型是 SOCK_STREAMtcp_socket = socket(AF_INET, SOCK_STREAM)# 2. 连接服务器server_ip = input('请输入要连接的服务器的ip:\t')server_port = input('请输入要连接的服务器的port:\t')server_addr = (server_ip, int(server_port))tcp_socket.connect(server_addr)# 3. 发送数据/接收数据send_data = input('请输入你要发送的数据:\t')tcp_socket.send(send_data.encode('utf-8'))# 4. 关闭套接字tcp_socket.close()if __name__ == '__main__':main()
    
-客户端更新版本1
  # !/usr/bin/env python# _*_ coding:utf-8 _*_# author:满怀心 2019/7/30 12:00"""# code is far away from bugs with the god animal protectingI love animals. They taste delicious.┏┓      ┏┓┏┛┻━━━┛┻┓┃      ☃      ┃┃  ┳┛  ┗┳  ┃┃      ┻      ┃┗━┓      ┏━┛┃      ┗━━━┓┃  神兽保佑    ┣┓┃ 永无BUG!   ┏┛┗┓┓┏━┳┓┏┛┃┫┫  ┃┫┫┗┻┛  ┗┻┛"""from socket import  *def main():# 1. 创建tcp套接字tcp_socket = socket(AF_INET, SOCK_STREAM)tcp_socket.bind(('', 5566))# 2. 绑定服务器的ip和端口server_ip = input('请输入对方服务器的ip地址:\t')server_port = input('请输入对方服务器的port端口:\t')server_addr = (server_ip, int(server_port))tcp_socket.connect(server_addr)# 3. 发/收数据while True:# 使用try捕捉 ctrl + ctry:send_data = input('请输入要发送的数据:\t')# 发送数据tcp_socket.send(send_data.encode('utf-8'))# 接收服务器信息recv_data = tcp_socket.recv(1024)print(recv_data.decode('utf-8'))# 跳出循环,关闭socketexcept KeyboardInterrupt:tcp_socket.send('quit()'.encode('utf-8'))break# 4. 关闭套接字tcp_socket.close()if __name__ == '__main__':main()
-客户端更新版本2(try-except)
 # !/usr/bin/env python# _*_ coding:utf-8 _*_# author:满怀心 2019/7/30 22:03"""# code is far away from bugs with the god animal protectingI love animals. They taste delicious.┏┓      ┏┓┏┛┻━━━┛┻┓┃      ☃      ┃┃  ┳┛  ┗┳  ┃┃      ┻      ┃┗━┓      ┏━┛┃      ┗━━━┓┃  神兽保佑    ┣┓┃ 永无BUG!   ┏┛┗┓┓┏━┳┓┏┛┃┫┫  ┃┫┫┗┻┛  ┗┻┛"""from socket import *import sysimport argparse# argparse 获取命令行参数,能后转换成函数内部的数据def text():parser = argparse.ArgumentParser(description='Socket Error Examples')parser.add_argument('--host', action='store', dest='host', required=False)parser.add_argument('--port', action='store', dest='port', type=int, required=False)parser.add_argument('--file', action='store', dest='file', required=False)given_args = parser.parse_args()host = given_args.hostport = given_args.portfilename = given_args.file# First try-except block  =>  creating sockettry:tcp_socket = socket(AF_INET, SOCK_STREAM)except error as e:print('Error creating socket : {}'.format(e))sys.exit(1)     # 退出try:# Second try-except block  =>  connecting to given host/porttry:tcp_socket.connect((host, port))except gaierror as e:print('Address-related error connecting to server : {}'.format(e))sys.exit(1)except error as e:print('Connection error : {}'.format(e))sys.exit(1)while True:# Third try-except block  =>  sending datatry:dest_data = input('请输入要传输的数据:\t').encode('utf-8')tcp_socket.send(dest_data)except error as e:print('Error sending data : {}'.format(e))sys.exit(1)# Fourth try-except block  =>  waiting to receive from remote hosttry:recv_data = tcp_socket.recv(2048)except error as e:print('Error receive data : {}'.format(e))sys.exit(1)if not recv_data:breakelse:print(recv_data.decode('utf-8'))except KeyboardInterrupt:tcp_socket.close()if __name__ == '__main__':text()

2.3,TCP服务端(重要)

# !/usr/bin/env python
# _*_ coding:utf-8 _*_
# author:满怀心 2019/7/30 12:36
"""
# code is far away from bugs with the god animal protectingI love animals. They taste delicious.┏┓      ┏┓┏┛┻━━━┛┻┓┃      ☃      ┃┃  ┳┛  ┗┳  ┃┃      ┻      ┃┗━┓      ┏━┛┃      ┗━━━┓┃  神兽保佑    ┣┓┃ 永无BUG!   ┏┛┗┓┓┏━┳┓┏┛┃┫┫  ┃┫┫┗┻┛  ┗┻┛
"""
from socket import *def main():# 1. 买个手机(创建套接字 socket)tcp_server_socket = socket(AF_INET, SOCK_STREAM)# 2. 插入手机卡(绑定本地信息 bind)tcp_server_socket.bind(('', 7891))# 3. 将手机设置为正常的响铃模式(让默认的套接字由主动变成被动 listen)tcp_server_socket.listen(128)# 4. 等待别人的电话到来(accept)print('-----等待接收-----')new_client_socket,client_addr = tcp_server_socket.accept()# accept方法生成一个元组,元组里是一个新的socket客户端,用来和接收到的客户端通信,并且这个新生成的socket客户端会带有接收到的socket客户端的信息来和你通信,就像拨打10086会给你接通到客服服务,但是10086还是处于被动接收状态,处理客户端的不是服务端,而是服务端产生的新的客户端,服务端只负责接收新的客户端请求并转接给新的客户端进行服务print('-----接收成功-----')print(client_addr)	# 打印客户端的信息# 接收客户端发过来的请求recv_data = new_client_socket.recv(1024)print(recv_data.decode('utf-8')) # 这个新的客户端带有请求的客户端的信息,不需要像元组一样# 回送数据给客户端new_client_socket.send('----------ok----------'.encode('utf-8'))# 关闭套接字tcp_server_socket.close()new_client_socket.close()if __name__ == '__main__':main()
-服务器更新版本
# !/usr/bin/env python
# _*_ coding:utf-8 _*_
# author:满怀心 2019/7/30 12:36
"""
# code is far away from bugs with the god animal protectingI love animals. They taste delicious.┏┓      ┏┓┏┛┻━━━┛┻┓┃      ☃      ┃┃  ┳┛  ┗┳  ┃┃      ┻      ┃┗━┓      ┏━┛┃      ┗━━━┓┃  神兽保佑    ┣┓┃ 永无BUG!   ┏┛┗┓┓┏━┳┓┏┛┃┫┫  ┃┫┫┗┻┛  ┗┻┛
"""
from socket import *def main():# 1. 买个手机(创建套接字 socket)tcp_server_socket = socket(AF_INET, SOCK_STREAM)# 2. 插入手机卡(绑定本地信息 bind)tcp_server_socket.bind(('', 2345))# 3. 将手机设置为正常的响铃模式(让默认的套接字由主动变成被动 listen)tcp_server_socket.listen(128)try:while True:# 4. 等待别人的电话到来(accept)print('----------等待客户端连接连接----------')# 监听服务器接收客户端请求,创造一个socket与其进行通信new_client_socket,client_addr = tcp_server_socket.accept()print('客户端 {}:{} 已经成功连接'.format(client_addr[0], client_addr[1]))while True:# 接收客户端发过来的请求recv_data = new_client_socket.recv(1024).decode('utf-8')print('接收数据 : {}'.format( recv_data))# recv_data 解堵塞:# 1. 客户端发送过来数据# 2. 客户端断开连接解堵塞# 客户端发送数据,解堵塞if recv_data:# 回送数据给客户端new_client_socket.send('----------ok,接收成功----------'.encode('utf-8'))# 客户端断开连接,解堵塞else:breakprint('客户端 {}:{} 已经成功断开\n'.format(client_addr[0], client_addr[1]))# 关闭套接字new_client_socket.close()except KeyboardInterrupt:# 5. 关闭服务器tcp_server_socket.close()if __name__ == '__main__':main()

2.4,TCP注意点

  1. tcp服务器一般情况下都需要绑定,否则客户端找不到这个服务器
  2. tcp客户端一般不绑定(可以在多个多开,不用担心端口被恶意程序霸占),因为是主动连接服务器,所以只要确定好服务器的ip,port等信息就好,本地客户端可以随机
  3. tcp服务器中通过listen可以将socket创建出来的主动套接字变为被动的,这是做tcp服务器时必须要做的
  4. 当客户端需要连接服务器时,就需要使用connect进行连接,udp是不需要连接的而是直接发送,但是tcp必须连接,只有连接成功才能通信
  5. 当一个tcp客户端连接服务器时,服务器会有1个新的套接字,这个套接字是用来标记这个客户端的,单独为这个客户端服务
  6. listen后的套接字是被动套接字,用来接收新的客户端的连接请求的,而accept返回的新套接字是标记这个新客户端的
  7. 关闭listen后的套接字就意味着被动套接字关闭了,会导致新的客户端不能够连接服务器,但是之前已经连接成功的客户端能够正常通信
  8. 关闭accept返回的套接字意味着这个客户端已经服务关闭
  9. 当客户端的套接字调用close后,服务器端会recv解堵塞,并且返回的长度为0,因此服务器可以通过返回数据的长度来区别客户端是否已经下线

更多推荐

网络编程(2)

本文发布于:2023-07-02 18:52:53,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/995080.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:网络编程

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!