python学习之网络

本文深入解析UDP和TCP两种网络编程模型,详述其发送、接收数据流程,包括套接字创建、绑定、监听、连接及数据交互过程。通过示例代码展示Python环境下具体实现方法。

一、UDP协议

1、UDP网络程序发送流程

  • 创建udp套接字(socket)
  • 发送数据(sendto)
  • 关闭套接字(close)
    与使用文件流程类似
    示例代码如下:
import socket
def main():
    #1、创建socket对象
    udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    #2、socket收发数据
    #发数据.注sendto(b"内容",用元组形式写ip和端口号)
    udp_socket.sendto(b"hello world!",("192.168.17.132",7908))
    #python3中input返回值是str型通过encode转换成bytes类型
    send_data = input("请输入\n")
    udp_socket.sendto(send_data.encode("gbk"),("192.168.0.103",8080))
    #关闭socket
    udp_socket.close();
if __name__=="__main__":
    main()

代码解析:
socket():
第一个参数是:Address Family,可以选择 AF_INET(用于 Internet 进程间通信) 或者 AF_UNIX(用于同一台机器进程间通信),实际工作中常用AF_INET
第二个参数:Type,套接字类型,可以是 SOCK_STREAM(流式套接字,主要用于 TCP 协议)或者 SOCK_DGRAM(数据报套接字,主要用于 UDP 协议)
sendto():
第一个参数是:发送的内容是bytes类型
第二个参数:是目的IP和端口是元组类型

2、udp接收数据流程

  • 创建udp套接字(socket)
  • 给套接字绑定ip和端口(bind)
  • 接收数据(recvfrom)
  • 关闭套接字(close)
    示例代码:
import socket
def main():
    #1、创建套接字
    udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    #2、绑定程序端口号及ip
    udp_localaddr = ("",7908)
    udp_socket.bind(udp_localaddr)
    #3、接收数据udp_receive_msg(接受的数据,(发送方的ip,端口号))
    udp_receive_msg = udp_socket.recvfrom(1024)
    udp_receive_data = udp_receive_msg[0]
    udp_receive_addr = udp_receive_msg[1]
    #4、处理数据(打印)
    print("%s:%s"%(str(udp_receive_addr),udp_receive_data.decode("gbk")))
    #5、关闭套接字
    udp_socket.close()
if __name__ == "__main__":
    main()

代码解析:
udp_localaddr = ("",7908):代表本机的ip
recvfrom():返回值是一个元组,元组第一个元素是接收的内容,bytes类型。第二个元素是发送方的ip及端口,会阻塞知道收到数据为止

二、TCP网络程序

1、tcp客户端网络程序流程

  • 创建tcp套接字(socket)
  • 连接服务器(connect)
  • 收/发送数据(recv/send)
  • 关闭套接字(close)

示例代码:

import socket


def main():
    #创建套接字
    tcp_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    #连接服务器
    server_ip = input("请输入server ip:")
    server_port = int(input("请输入server port:"))
    server_addr = (server_ip,server_port)
    tcp_socket.connect(server_addr)
    #发送接收数据
    send_data = input("请输入要发送的内容:")
    tcp_socket.send(send_data.encode("utf_8"))
    #关闭套接字
    tcp_socket.close()
if __name__ == "__main__":
    main()


2、tcp服务器流程

  • 创建tcp套接字(socket)
  • 绑定套接字(bind)
  • 监听客户端(listen)
  • 等待客户端连接(accept)
  • 接收/发送数据(recv/send)
  • 关闭套接字 (close)

示例代码:

import socket


def main():
    #创建套接字(socket)
    tcp_sever_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    #绑定端口及ip(bind)
    server_ip = ""
    server_port = 7788
    server_addr = (server_ip,server_port)
    tcp_sever_socket.bind(server_addr)
    #将套接字设置成监听模式(listen)
    while True:
        tcp_sever_socket.listen(128)
        #等待客户端连接(accept)
        print("阻塞1,等待客户端连接(accept)")
        new_client_socket,new_client_socket_addr = tcp_sever_socket.accept()
        #收发数据(send/recv)
        print("阻塞2,等待客户端发送的数据(recv)")
        receive_data = new_client_socket.recv(1024)
        print("%s: %s" %(str(new_client_socket_addr),receive_data.decode("utf-8")))
    #关闭客户端套接字(close)
    new_client_socket.close()
if __name__ == "__main__":
    main()

代码解析:
listen():将套接字改为被动监听模式,TCP服务器必须改为被动模式
accept():返回值有两个,第一个是为连接进来的客户端创建新的套接字对象(new_client_socket),之后与该客户端收发用的套接字都是该套接字fa,而开始创建的套接字(tcp_sever_socket)是服务器用来监听的套接字,第二个参数是连接进来的客户端的IP及端口,是元组类型,accept当没客户端连接进来时会阻塞,知道有客户端连接进来时接阻塞。
recv():返回值只有接收到的内容(不像recvfrom那样还带有发送方的IP及端口)是bytes类型

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

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值