手记

Python基础系列讲解——TCP协议的socket编程

前言

我们知道TCP协议(Transmission Control Protocol, 传输控制协议)是一种面向连接的传输层通信协议,它能提供高可靠性通信,像HTTP/HTTPS等网络服务都采用TCP协议通讯。那么网络通讯方面都会涉及到socket编程,当然也包括TCP协议。Python作为一门适应于快速开发的工具,在它浩瀚的第三方库中也一定包括了socket模块,那么本文就给大家介绍Python的socket编程实现TCP协议连接的方法。

socket介绍

socket(套接字)起源于UNIX,主要用于网络进程间通讯,它是在应用层和传输层之间的一个软件抽象层,它把TCP/IP复杂的操作抽象为几个简单的接口供应用层调用来实现进程在网络中的通信。因为在Unix中一切皆为文件,所以socket通过"open—read/write—close"模式来实现进程在网络中的通信。服务器和客户端各自维护一个"文件",建立连接后相当于打开了文件,各自可以向自己文件写入内容供对方读取或者读取对方内容,通讯结束时则关闭文件。

TCP连接流程

socket主要以"open—read/write—close"的模式来实现客户端和服务器之间TCP协议的连接,交互流程如下图所示。TCP服务器的建立可以归纳这几步:1)创建socket(套接字);2)绑定socket的ip地址和端口;3)监听客户端的连接请求;4)接受客户端的连接请求;5)与客户端对话;6)关闭连接。TCP客户端的创建可总结为这几步:1)创建socket(套接字);2)连接服务器socket;3)与服务器对话;4)关闭连接。

需要注意的是TCP客户端连接到服务器的ip和端口要与TCP服务器监听的ip和端口相同,服务器调用listen()开始监听端口,而后调用accept()时刻准备接受客户端的连接请求,此时服务器处于阻塞状态,直到服务器监听到客户端的请求后,接收请求并建立连接为止。

TCP服务器/客户端例程

提供给大家两个Python实现socket连接例程,一个为TCP服务器和客户端的短连接例程,即服务器接受客户端连接后创建一个线程,在线程中与客户端收发数据后关闭连接,另一个为TCP服务器和客户端的长连接例程,服务器与客户端建立连接后彼此循环收发数据,不关闭连接。

这里要注意的是服务器接收客户端发送数据时是处于阻塞状态的。server.close()是关闭服务端的socket程序本身的连接,关闭后整个服务端socket程序就退出运行。client_socket.close()是关闭服务端socket程序与客户端的连接,关闭后服务端的socket程序仍然还在运行。

TCP服务器短连接实现
import socket
import threading

bind_ip = "127.0.0.1"
bind_port = 12345

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((bind_ip, bind_port))#bind ip and port 
server.listen(5)#start listen max connection

print "[*] listening on %s:%d" % (bind_ip, bind_port)

def handle_client(client_socket):

	request = client_socket.recv(1024)
	print "[*] Received: %s" % request
	client_socket.send('ACK!')
	client_socket.close()
	
while True: 
    client, addr = server.accept()
    print "[*] Accepted connection from: %s:%d" % (addr[0], addr[1])
    client_handler = threading.Thread(target=handle_client, args=(client,))
    client_handler.start()
server.close()
TCP客户端短连接实现
import socket

target_host = '127.0.0.1'
target_port = 12345

#Creat socket object  AF_INET means use the normod IPv4 address and hots name;OCK_STREAM one tcp client
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((target_host, target_port))
client.send("i am TCP client")

response = client.recv(4096)
print response
TCP服务器长连接实现
import socket
import threading

bind_ip = "127.0.0.1"
bind_port = 12345

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((bind_ip, bind_port))#bind ip and port 
server.listen(5)#start listen max connection
print "[*] listening on %s:%d" % (bind_ip, bind_port)

while True:
    
    client, addr = server.accept()
    print "[*] Accepted connection from: %s:%d" % (addr[0], addr[1])

    while True:
        request = client.recv(1024)	
        print "[*] Received: %s" % request
        client.send('ACK!')
        print "[*] Sended: ACK!"
    client.close()

server.close()
TCP客户端长连接实现
import socket

target_host = '127.0.0.1'
target_port = 12345

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((target_host, target_port))

while True:
	client.send("TCP client connect")
	response = client.recv(4096)
	print response
8人推荐
随时随地看视频
慕课网APP

热门评论

while True后面的close还有必要吗

 socket.setblocking(1)是设置阻塞模式收发数据
 socket.setblocking(0)是设置非阻塞模式收发数据

查看全部评论