TCP和UDP编程

此博客链接:https://www.cnblogs.com/ping2yingshi/p/14388417.html

1.UDP编程

1.1说明

1.名字

客户端名字:UDPClient

服务器名字:UDPServer

2.运行环境

Python 3.8.5

3.通信过程

 UDP连接时,需要先开启服务端,客户端向服务端发送数据前,双方先创建套接字,创建完套接字之后,双方进入到数据收发阶段,最后通信结束。

1.2代码

1.2.1说明

1.2.1.1UDPClient

1.socket 建立UDP的套接字。

2.clientSocket.sendto()向UDP服务端发送数据。

3.SOCK_DGRAM 代表 UDP连接。

1.2.1.2UDPServer

1.serverSocket.bind()将IP地址,端口号与服务端的套接字绑定。

2.message,clientAddress=serverSocket.recvfrom(1024)

1.2.2UDPClient

import socket
BUFSIZE = 1024
#创建套接字
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
ip_port = ('127.0.0.1', 8081)
while True:
# 获取用户输入
msg = input(">> ").strip()
# 向服务端发送用户数据
client.sendto(msg.encode('utf-8'), ip_port)
# 接收对方发送过来的数据,最大接收1024个字节
data, server_addr = client.recvfrom(BUFSIZE)
print('客户端recvfrom ', data, server_addr)

client.close()

1.2.3UDPServer

import socket
BUFSIZE = 1024
ip_port = ('127.0.0.1', 8081)
#创建套接字
server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # udp协议
#绑定IP和端口号
server.bind(ip_port)
while True:
# 接收对方发送过来的数据,最大接收1024个字节
data, client_addr = server.recvfrom(BUFSIZE)
print('server收到的数据', data)
# 向客户端发送服务端数据
server.sendto("thank you !".encode('utf8'), client_addr)
server.close()

1.3实验过程

1.先运行UDPServer.py,打开服务端。

2.再运行UDPClient.py,打开客服端,输入123。

3.在服务器端接收到123数据。

4.动图展示

打开UDPServer后,再打开UDPClient并输入123,在UDPServer收到123。

1.4通信过程

1.4.1说明

抓包工具:Wireshark

1.4.2过程

1.客户端client 发送数据

2.服务端server接收数据

3.抓包数据

wireshark 设置过滤UDP抓包参数为:"udp.port==8081",(代码udp 服务端设置绑定端口号为8081)

根据上图可知:UDP的端口号为8081。

第一条数据是客户端向服务器发送字节长度为2的"YP"数据。

第二条数据是服务器收到客户端发送的数据并向客服端发送长度为11的“thank you!”数据。

第三条数据是客户端向服务器发送字节长度为5的"nihao"数据。

第四条数据是服务器收到客户端发送的数据并向客服端发送长度为11的“thank you!”数据。

2.TCP编程

2.1说明

1.名字

客户端名字:TCPClient

服务器名字:TCPServer

2.运行环境

Python 3.8.5

3.通信过程

 TCP连接时,需要先开启服务端,客户端向服务端发送数据前,双方先创建套接字,创建完套接字之后,客户端会向服务器发起连接操作,连接操作完成后,双方进入到数据收发阶段,最后客户端先发起断开连接诶,服务端随后断开连接。

2.2代码

2.2.1说明

2.2.1.1TCPClient

1.创建客户端socket套接字
2.客户端套接字主动连接服务端套接字(提供服务端套接字绑定的ip和端口号)
3.客户端套接字向服务端套接字发送数据

2.2.1.2TCPServer

1.创建socket套接字
2.给socket绑定ip和端口号
3.开始 TCP 监听,等待客户端连接

4.服务端接收并处理客户端发送的数据

2.2.2TCPClient

from socket import *
from pip._vendor.distlib.compat import raw_input
#目的信息
serverName ='localhost'
serverPort =14000
#创建套接字
clientSocket =socket(AF_INET,SOCK_STREAM)
#建立连接
clientSocket.connect((serverName,serverPort))
#获取用户输入
sentence =raw_input('Input lowercase sentence:')
#向服务端发送用户数据
clientSocket.send(bytes(sentence,encoding='utf8'))
# 接收对方发送过来的数据,最大接收1024个字节 
modifiedSentence=clientSocket.recv(1024); 
print ('From Server:',modifiedSentence) 
clientSocket.close()

2.2.3TCPServer

from socket import *
from pip._vendor.distlib.compat import raw_input
#本地信息
serverName ='localhost'
serverPort =14000
#创建套接字
serverSocket =socket(AF_INET,SOCK_STREAM)
serverSocket.bind((serverName,serverPort))
print("This server is ready to receive")
#监听来自客户端的TCP链接
serverSocket.listen(serverPort)
while True:
#创建新的套接字
    connectionSocket=serverSocket.accept()
# 接收对方发送过来的数据,最大接收2048个字节 
    sentence=connectionSocket.recvfrom(2048) 
#获取由客户发送的行并使用upper()方法将其转换为大写
    capitalizedSentence=sentence.upper() 
    if sentence:
         print("接受到的数据是:",sentence) 
#向客户端发送数据
    connectionSocket.send(capitalizedSentence)
#关闭连接
    connectionSocket.close()

2.3实验过程

1.先运行TCPServer.py,打开服务端,当运行程序时,程序报错,显示无法连接。

2.查阅资料,在accept之前,应该打开listen进行监听。

 

3.再次运行TCPServer.py,打开了服务端。

 4.运行TCPClient.py,打开客户端,发送数据123,显示主机的软件中止了一个已建立的连接。

 5.修改错误

(1)TCPServer中的recvfrom修改成recv,recvfrom是UDP中的通信。

(2)接收套接字时,根据python语法,需要把元组中的所有元素都获取,添加clientAddr=serverSocket.accept()语句

accept函数返回元组。

 6.正确代码

(1)TCPServer

#!/usr/bin/python
# -*- coding: UTF-8 -*-
# 文件名:tcp-server.py
from socket import *
# 创建socket
tcp_server_socket = socket(AF_INET, SOCK_STREAM)
# 本地信息
address = ('localhost', 8080)
# 绑定
tcp_server_socket.bind(address)
# 使用socket创建的套接字默认的属性是主动的,使用listen将其变为被动的,这样就可以接收别人的连接了
# listen里的数字表征同一时刻能连接客户端的程度.
tcp_server_socket.listen(5)
print("This server is ready to receive")
while True:
# 如果有新的客户端来连接服务器,那么就产生一个新的套接字专门为这个客户端服务
# client_socket用来为这个客户端服务
# tcp_server_socket就可以省下来专门等待其他新客户端的连接
# clientAddr 是元组(ip,端口)
client_socket, clientAddr = tcp_server_socket.accept()
print("client连接地址信息为:", clientAddr)
# 接收对方发送过来的数据,和udp不同返回的只有数据
recv_data = client_socket.recv(1024) # 接收1024个字节
print('server接收到的数据为:', recv_data.decode('utf8'))
# 发送一些数据到客户端
client_socket.send("thank you !".encode('utf8'))
# 关闭为这个客户端服务的套接字,只要关闭了,就意味着为不能再为这个客户端服务了,如果还需要服务,只能再次重新连接
client_socket.close()

 (2)TCPClient

#!/usr/bin/python
# -*- coding: UTF-8 -*-
# 文件名:tcp-client.py
from socket import *
# 创建socket
tcp_client_socket = socket(AF_INET, SOCK_STREAM)
# 目的信息
server_ip = 'localhost'
server_port = 8080
# 连接服务器
tcp_client_socket.connect((server_ip, server_port))
# while True:
# 提示用户输入数据
send_data = input("请输入client要发送的数据:")
# 发送数据
tcp_client_socket.send(send_data.encode("utf8"))
# 接收对方发送过来的数据,最大接收1024个字节
recvData = tcp_client_socket.recv(1024)
print('client接收到的数据为:', recvData.decode('utf8'))
# 关闭套接字
tcp_client_socket.close()

7.动图展示

打开TCPServer后,再打开TCPClient并输入123,在TCPServer收到123。

2.4通信过程

2.4.1说明

抓包工具:Wireshark

 

2.4.2过程

1.客户端client 发送数据

2.服务端server接收数据,其中客户端地址显示端口号为56070

3.抓包数据

 wireshark 设置过滤TCP抓包参数为:"tcp.port==8080",(代码tcp 服务端设置绑定端口号为8080)

根据上图可知:图中前三条数据是客户端向服务端发起连接操作。

第一条数据表示:客户端生成一个SYN为1的TCP包并发送给服务器。这个TCP包的头部还包含了客户端发送数据时需要用到的窗口大小8192。

第二条数据表示:当这个包到达服务器之后,服务器会返回一个SYN为1的TCP包。这个包也包含了序号和窗口大小,还包含了表示确认已经收到包的ACK号。

第三条数据表示:客户端向服务器返回一个包表示确认的ACK号的TCP包。

图中的中间四条数据是客户端和服务端发送数据过程。

第一条数据是客户端向服务器发送数据"yp"字节长度为2并返回一个包表示确认的ACK。

第二条数据是服务器收到客户端发送的数据并返回ACK=3的确认包。

第三条数据是服务端向客户端发送的数据"thank you !"字节长度为11并返回ACK=3的包。

第四条数据是客户端接收到服务端的数据并返回ACK=12的包。

图中最后四条数据是客户端和服务端关闭连接。

第一条数据是服务端向客户端发送FIN,表示服务端没有数据要发送给客户端了。

第二条是客户端接收到服务端的FIN报文段,向服务端发送一个ACK报文段。

第三条是客户端向服务端发送FIN,请求关闭连接。

第四条是服务端接收到客户端发送的FIN报文段,向客户端发送ACK报文段,至此客户端和服务端关闭连接。

posted @ 2021-02-08 12:49  萍2樱释  阅读(234)  评论(0编辑  收藏  举报