第十一篇:socket编程(一)

  本篇主要介绍网络编程的基础,以及UDP/TCP网络的socket编程,。。。

一、网络通信

  关于网络通信即通过网络(介质)来进行信息的交换(数据的接收和发送),而需要实现一台终端与另一台终端的通信,首先我们需要找到那台终端,那么我们怎么找到那台终端或者说通过什么找到那台终端进行通信呢?这里就需要IP地址;那通过IP地址找到了那台终端就可以吗?在一台终端上可能运行了许多进程(如QQ、微信、陌陌等用户程序),那么我们怎么才能找到该终端上的需要进行通信的用户程序呢(进程)?这里就需要端口port;

 IP地址:

  IP地址:用来表示网络上的一台终端的,例如:192.168.13.55等,在一个局域网内IP地址具有唯一性;

  端口port:

  端口port:端口就像一个房子的房门,一台终端可以同时运行很多应用程序即进程就像房子可以有很多门,而每个门均有其门牌号,而端口也是通过端口号来标记的,端口号只有整数,范围是从0到65535。

  端口可以分为:

    1、知名端口,即众所周知的端口号,其范围为:0--1023;由于一个端口只能标识一个应用程序,故如果一个程序需要使用知名端口的需要有root权限。

    2、动态端口,其范围为:1024--65335。即指当一个系统程序或应用程序程序需要网络通信时,它向主机申请一个端口,主机从可用的端口号中分配一个供它使用,而当这个程序关闭时,该程序所占用端口就会被释放。

之所以称为动态端口,是因为它一般不固定分配某种服务,而是动态分配。

扫描二维码关注公众号,回复: 1943939 查看本文章

  以上可知,我们知道了目标IP地址和端口号,就可以找到对方的终端以及其终端中需进行通信的进程;那么我们怎么实现通信呢?这里就需要接下来的socket编程。

二、socket

  1、在学习socket之前我们需要知道我们为什么要学习它?

  可能很多人都听说过C/S架构,即client/server架构(客户端/服务端架构),而C/S架构有硬件C/S架构(打印机),软件C/S架构(如百度网站就是服务端,而我的浏览器就是客户端,当然也有人讲这为B/S架构等);而我们学习socket就是为了实现C/S架构,在一定程度上也可以说为了实现网络通信;

  2、什么是socket?

  其实socket在python中就是其中的一个模块,而具体来说Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

  

  注:也有人将socket说成ip+port,ip是用来标识互联网中的一台主机的位置,而port是用来标识这台机器上的一个应用程序,ip地址是配置到网卡上的,而port是应用程序开启的,ip与port的绑定就标识了互联网中独一无二的一个应用程序,而程序的pid是同一台机器上不同进程或者线程的标识。

  3、UDP协议下socket的实现

  基于UDP协议下的网络程序的socket发送、接收流程如下:

    

  基于UDP协议socket实现信息的发送:

import socket
def main():
    # 1.创建套接字对象
    udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
# 2、确定目标IP地址和端口,发送数据 aim_addr=("192.168.11.68",8080) # 目标IP地址和端口号,以元组的形式传入 send_content=input("please enter what you want to send:") #由于数据的传输和存储必须以字节的格式进行 udp_socket.send_to(send_content.encode("uft-8"),aim_addr)
# 3、关闭套接字对象 udp_socket.close() if __name__=="__main__": main()

  基于UDP协议socket实现信息的接收:

import socket
def main():
    # 1.创建套接字对象
    udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

    # 2、绑定本地终端及进程的信息
    udp_socket.bind(("",7878))

    # 3、接收数据,并对接收的数据进行解析
    recv_data=udp_socket.recvfrom(1024)
    recv_content=recv_data[0].decode("gbk")  # 数据的传输是以二进制的形式,故需知对方的编码格式进行解码
    recv_addr=recv_data[1]

    # 4、将解析的数据打印到屏幕上
    print("%s send %s to you ."%(recv_addr,recv_content))
# 5、关闭套接字 udp_socket.close() if __name__=="__main__": main()

  

  当然,也可以实现接收和发送:

import socket
def main():
    # 1.创建套接字对象
    udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

    # 2、绑定本地终端及进程的信息
    udp_socket.bind(("",7878))
    aim_addr=("192.168.11.68",8080)  # 目标IP地址和端口号,以元组的形式传入

    while True:
        #发送
        send_content=input("please enter what you want to send:")
        if send_content == "exit":
            break
        udp_socket.send_to(send_content.encode("uft-8"),aim_addr)

        #接收    
        recv_data=udp_socket.recvfrom(1024)
        recv_content=recv_data[0].decode("gbk") 
        recv_addr=recv_data[1]
        # 4、将解析的数据打印到屏幕上
        print("%s send %s to you ."%(recv_addr,recv_content))
    # 5、关闭套接字
    udp_socket.close()

if __name__=="__main__":
    main()
基于UDP协议的socket接收和发送

  上述的形式,只能实现必须等发送完了才能进行接收,这是由于其中input和recvfrom均为一种阻塞机制,只有等它们执行完成才会继续执行下一步。故若想实现随时发送,随时接收的功能,则需应用到后面的多进程等知识。故后面再进行补充。

  

猜你喜欢

转载自www.cnblogs.com/littlefivebolg/p/9278606.html