计网实验原理-TCP/UDP套接字编程

 

计算机网络自顶向下结构——第7版

第二章实验,套接字编程

代码运行环境:window10,python 3.8.对于书上代码略作修改。

进程与计算机网络之间的接口

多数应用程序是由通信进程队组成的,每对中的两个进程互相发送报文。而从一个进程向另外一个进程发送的报文必须经过下面的网络。进程通过一个称为套接字的软件接口向网络发送报文和从网络接收报文。

简单理解一下:如果把一个进程比作一座房子,那么套接字就可以类比为他的门。当一个进程想要向位于另一台主机上的另一个进程发送报文的时候,他要向把报文推送出门,该发送进程假定该门到门外一侧之间有运输的基础设施,该设施会把报文传送到目的进程的门口。一旦报文抵达目的主机,它就会通过接收进程的门传递,然后接收进程对该报文进行处理。

计网实验原理-TCP/UDP套接字编程_第1张图片

如上图所示,套接字是同一台主机内层应用程序和网络之间的接口。由于其建立网络应用程序的可编程接口,所以也叫做应用程序和网络之间的应用编程接口(API application programming interface)

应用层虽然可以空hi套接字在顶层应用端的一切,但是对于套接字的运输层几乎没有控制权。嗯,仅限于:选择运输层协议,或者说可以设定几个参数,简单类似于最大缓存最大报文端长度等。

UDP交互过程

结用上面的理解,

  1. 在发送进程能够将数据分组退出套接字门之前,当使用UDP时,必须先将目的地址附在该分组之上。
  2. 在该分组传过发送方的套接字之后,因特网使用该目的的地址通过因特网为该分组选路到接收进程的套接字。
  3. 当分组到达接收套接字时,接收进程将通过该套接字取回分组,然后检查分组内容并采取适当措施。

附在分组的目的地址包括:

  1. 目的主机的IP地址,用于路由选路找到网络中正确的目的主机
  2. 包含目的进程的端口号,用于区分目的主机中是哪一个进程使用的哪一个套接字。

同样,发送方的IP地址和端口地址也要附在分组中,便于回信——这个操作是由底层操作系统自动完成。

应用程序功能

使用简单的客户-服务器应用程序来演示对于UDP和TCP的套接字编程:

  1. 首先,客户应用程序从其键盘读取一行字符数据并将数据向服务器发哦是那个
  2. 然后,服务器接收该数据并将这些字符转换为大写
  3. 服务器将修改的数据发送给客户
  4. 客户接收修改的数据并显示

UDP套接字流程:

计网实验原理-TCP/UDP套接字编程_第2张图片

 

UDP套接字编程

UDPCLient.py

from socket import *
serverName = 'hostname' #这里的hostname使用自己主机的IPv4地址,也可以使用自己电脑的名字
serverPort = 12000
clientSocket = socket(AF_INET,SOCK_DGRAM)#参数的意思可以看我给的两个博客
message = input('Input lowercases sentence:')
clientSocket.sendto(message.encode(),(serverName,serverPort))
modifiedMessage,serverAddress = clientSocket.recvfrom(2048)
print(modifiedMessage.decode())
clientSocket.close()

AF_INET域与AF_UNIX域socket通信原理对比

流式套接字(SOCK_STREAM),数据报套接字 (SOCK_DGRAM) 的比较

from socket import *
serverPort = 12000
serverScoket = socket(AF_INET,SOCK_DGRAM)
serverScoket.bind(('',serverPort))
print("The server is ready to receive")
while True:
    message, clientAddress =serverScoket.recvfrom(2048)
    modifiedMessage = message.decode().upper()
    serverScoket.sendto(modifiedMessage.encode(), clientAddress)

运行结果:
 

关闭server:
 

计网实验原理-TCP/UDP套接字编程_第3张图片

TCP套接字编程

TCP是一个面向连接的协议。

意味着客户与服务器开始交换数据之前必须建立一个TCP连接。

创建TCP连接时,我们将客户套接字地址于服务器套接字地址关联起来。使用连接时,当一次要向另外一侧发送数据时,他只需要经过其套接字将数据丢进TCP连接。这就与UDP不同,UDP服务器将数据丢进套接字前必须附加一个目的地址。

TCP交互

客服具有向服务器发起接触的任务。服务器为了能够对客户的初始接触做出反应,服务器必须提前准备好。这意味着:

  1. 与使用UDP类似,TCP服务器在客户试图发起接触前必须作为进程运行起来。
  2. 服务器必须有一扇特殊的门(套接字),这门欢迎来自运行在任意主机上的客户进程的初始接触(knock the door)

在服务器运行的时候,客户创建一个TCP套接字即可以向服务器发起一个TCP连接。客户生成套接字时,指定了服务器套接字的地址,即服务主机IP和其套接字端口。然后发起三次握手并创建一份与服务器的TCP连接。

发送在运输层的三次握手,对于客户和服务器程序来说是完全透明的。

服务器在第一次收到客户的接触(knock the door)时,他会新生成一个套接字,用于特定的用户。新生成的套接字也叫做连接套接字。

计网实验原理-TCP/UDP套接字编程_第4张图片

通信过程

计网实验原理-TCP/UDP套接字编程_第5张图片

TCPClient.py

from socket import *
serverName = 'servername'
serverPort = 12000
clientSocket = socket(AF_INET,SOCK_STREAM)
clientScoket.connect((serverName,serverPort))
sentence = raw_input('Input lowercase sentence:')
clientSocket.send(sentence.encode())
modiefiedSentence = clientSocket.recv(1024)
print('From Server: ',modifiedSentence.decode())
clientSocket.close()
#TCPServer.py
from socket import *
serverPort = 12000
serverSocket=socket(AF_INET,SOCK_STREAM)
serverSocket.bind(('',serverPort))
serverSocket.listen(1)
print('The server is ready to receive')
while True:
    connectionSocket,addr = serverSocket.accept()
    sentence = connectionSocket.recv(1024).decode()
    capitalizedSentence = sentence.upper()
    connectionSocket.send(capitalizedSentence.encode())
    connectionSocket.close()

运行结果

关闭server:
 

你可能感兴趣的:(计算机网络)