与UDP不同,TCP是一个面向连接的协议。这意味着,在客户端和服务器能够开始互相发送数据之前,它们要先握手和创建一个TCP连接。连接建立之后,当有一方需要给另一方发送数据,它只需经套接字把数据丢个TCP连接,无需再为数据附上目的地地址。
1. 下面讨论一下TCP客户程序和服务程序的交互,
①客户程序具有发起接触的任务。而服务程序为了能够对接触做出反应,它必须先运行起来,并且具有一个欢迎套接字欢迎任意客户程序的接触。
②客户进程生成套接字,与服务进程进行三次握手后,服务进程生成一个新的连接套接字(这对客户程序和服务器程序是完全透明的),客户进程与服务器进程建立起一个TCP连接。
③双方通过这一个TCP连接发送和接受数据。
如图1所示。
2. 接下来使用简单的客户-服务器应用程序来展示TCP套接字编程:客户向服务器发送一行数据,服务器将其改为大写并返回客户。图2注重显示了客户和服务器的主要与套接字相关的活动:客户程序只需要知道服务程序的IP和欢迎套接字的端口号。而TCP连接的建立由运输层完成:
以下代码在python3中测试通过:
(1)客户程序
from socket import *
serverName='127.0.0.1' #服务器的IP地址或主机名(这里是本地回送地址)
serverPort=12000
#第一个参数AF_INET表明底层网络使用IPv4,
#第二个参数SOCK_STREAM表明它是一个TCP套接字(而不是UDP)
clientSocket=socket(AF_INET,SOCK_STREAM)
#connect()执行完后,执行三次握手,并在客户和服务器程序之间创建起一条TCP连接
clientSocket.connect((serverName,serverPort))
sentence=input('Input lowercase sentence:')
#进入客户套接字,并通过TCP连接发送数据
#无需附上目的地地址
clientSocket.send(sentence.decode())
#当字符到达套接字时,它们被放在modifiedSentence,其缓存长度为2048
#知道收到回车符才会结束该行
modifiedSentence=clientSocket.recv(2048)
print('From Server:',modifiedSentence.encode())
clientSocket.close()
(2)服务器程序
from socket import *
serverPort=12000
#创建一个欢迎套接字serverSocket,将其绑定在serverPort上
serverSocket=socket(AF_INET,SOCK_STREAM)
serverSocket.bind(('',serverPort))
#聆听来自客户的连接请求;参数1表示请求连接的最大数
serverSocket.listen(1)
print('The server is ready to receive.')
while True:
#当有客户敲门时,seerverSocket调用accept(),
#在服务器中创建一个叫connectionSocket由这个客户专用
connectionSocket,addr=serverSocket.accept()
sentence=connectionSocket.recv(2048)
capitalizedSentence=sentence.upper()
connectionSocket.send(capitalizedSentence)
#关闭连接套接字,没有关闭欢迎套接字
connectionSocket.close()
测试时,应先保持服务器程序的运行,再运行客户程序。
等你掌握了更先进的套接字程序后,能编写自己的流行网络应用程序,变得非常富有和声明卓著了,请记得本书作者:James F. Kurose, Keith W. Rose !哈哈~