python之网络编程

为了实现在不同的电脑之间的通信,就需要使用网络编程。

TCP/IP简介:

互联网协议包含了上百种协议标准,其中最重要的两个协议就是TCP和IP协议

1、IP协议:

IP协议负责把数据从一台计算机通过网络发送到另一台计算机,由于互联网链路复杂,两台计算机之间经常有多条线路,因此,路由器就负责决定如何把一个IP包转发出去,IP包的特点是按块发送,途径多个路由,但是不保证都能到达,也不能保证顺利到达

2、TCP协议:

TCP协议是建立在IP协议之上的,TCP协议负责在两台计算机之间建立连接,保证数据包按顺序到达,通过3次握手建立可靠性连接,然后需要对每个IP包进行编号,确保对方按顺序收到,如果包丢掉了就自动重发。

UDP简介:

相对于TCP协议,UDP协议则是面向无连接的协议,使用UDP协议时,不需要建立连接,只需要知道对方的IP和端口号,就可以发送数据包,但是数据无法保证一定到达,虽然使用UDP传输数据不可靠,但它的优点是传输速度快,如果不要求可靠性到达的数据而言,可以考虑使用UDP协议

Socket简介:

为了让两个程序之间通过网路进行通信,二者均必须使用Socket套接字,通常也称为套接字,用于描述IP地址和端口,它是一个通信链的句柄,用于实现不同虚拟机或不同计算机之间的通信。

在Python中,使用socket模块的socket()函数就可以完成,语法格式如下:

s = socket.socket(AddressFamily,Type)

  • Address Family:可以选择AF_INET(用于Internet进程间通信),或者AF_UNIX(用于同一台计算机进程间通信),实际工作中常用AF_INET
  • Type:套接字类型,可以是SOCK_STREAM(流式套接字,主要用于TCP协议)或者SOCK_DGRAM(数据包套接字,主要用于UDP协议)

例如:通过下面方式创建TCP或者UDP套接字,如图:

注意:上面的socket.socket()中不加任何参数,默认情况下就是创建TCP套接字

创建完成后,生成一个socket对象,socket对象主要方法如下:

函数描述
s.bind()绑定地址(host,port)到套接字,在AF_INET下,以元组(host,port)形式表示地址
s.listen()开启TCP监听,参数为在拒绝连接之前,操作系统可以挂起的最大连接数量,一般设置为5
s.accept()被动接受TCP客户端连接(阻塞式),等待连接到来
s.connect()主动初始化TCP连接,参数的格式一般为元组(hostname,port),如果连接出错,返回socket.error错误
s.recv()接受TCP数据,数据以字符串形式返回,参数可以指定最大数据量
s.send()发送TCP数据,将string中的数据发送到连接的套接字,返回值是要发送的字节数量
s.sendall()完整发送TCP数据,将string中的数据发送到连接的套接字,在返回之前会尝试发送所有数据,成功返回None,失败抛出异常
s.recvfrom()接受UDP数据,与recv()类似,返回值是(data,address),其中data是包含接受数据的字符串,address是发送数据的套接字地址
s.sendto()发送UDP数据,将数据发送到套接字,address形式为(ipaddr,port)的元组,指定远程地址,返回值是发送的字节数
s.close()关闭套接字

TCP编程

1、创建TCP服务器:

如果要完成一个TCP服务器的功能,需要的流程如下:

  • 使用socket()创建一个套接字
  • 使用bind()绑定IP和port
  • 使用listen()使套接字变为可被动连接
  • 使用accept()等待客户端连接
  • 使用recv/send()接受和发送数据

例如:使用socket模块,通过客户端浏览器向本地服务器(127.0.0.1)发起请求,服务器接收到请求,向浏览器发送helloworld,创建一个server.py文件,如图 :

此时通过浏览器访问,结果如下:

2、创建TCP客户端:

上面的例子中是用浏览器作为客户端来接收数据,下面,创建一个TCP客户端,通过该客户端向服务器发送和接受消息,创建一个client.py,如图:

接下来同时启动第一步的服务端server.py和上图中的客户端client.py,然后在客户端中输入数据,服务器可以返回数据,如图:

3、执行TCP服务器和客户端

下面的例子实现了客户端和服务端的简易聊天,当有一方输入byebye后就退出,如图:

#服务端的代码
import socket
host = socket.gethostname()  #获取主机地址
port = 12345
s = socket.socket()          #创建TCP套接字
s.bind((host,port))          #绑定主机地址和端口
s.listen(1)                  #设置最多连接数量
sock,addr = s.accept()       #被动接受TCP客户端连接
info = sock.recv(1024).decode() #decode()将byte类型转换为字符串
while info != 'byebye':
    if info:
        print("接受到的内容为:",info)
    send_data = input("输入发送内容:")
    sock.send(send_data.encode()) #发送TCPshuju
    if send_data == 'byebye':     #如果发送byebye就推出
        break
    info = sock.recv(1024).decode() #接受客户端数据
sock.close()                        #关闭客户端套接字
s.close()                           #关闭服务器套接字
#客户端代码
import socket
s = socket.socket()             #创建TCP套接字
host = socket.gethostname()
port = 12345
s.connect((host,port))
info = ''
while info != 'byebye':
    send_data = input("请输入发送内容:")
    s.send(send_data.encode())
    if send_data == 'byebye':
        break
    info = s.recv(1024).decode()
    print("接受到的内容是:",info)
s.close()

标签