基于Tcp和UDP的python网络编程案例详解

news/2024/5/18 13:38:43 标签: python, socket, udp

文章目录

  • TCP和UDP网络编程
    • 1.通信协议介绍
    • 2.TCP协议和UDP协议
    • 3.Socket(套接字)
    • 4.TCP简单网络编程
    • 5.UDP简单网络编程

TCP和UDP网络编程

1.通信协议介绍

(1)定义:网络通信协议是一种网络通用语言,为连接不同操作系统和不同硬件体系结构的互联网络引提供通信支持,是一种网络通用语言。

(2)网络通信协议由三个要素组成。

语义,解释控制信息每个部分的意义。它规定了需要发出何种控制信息,以及完成的动作与做出什么样的响应。
语法,用户数据与控制信息的结构与格式,以及数据出现的顺序。
时序,对事件发生顺序的详细说明。
可以形象地把这三个要素描述为:*语义表示要做什么,语法表示要怎么做,时序表示做的顺序。

(3)常见协议
常见的网络通信协议有:TCP/IP协议、IPX/SPX协议、NetBEUI协议等。

TCP/IP参考模型是首先由ARPANET所使用的网络体系结构,共分为四层:网络接口层(又称链路层)、网络层(又称互联层)、传输层和应用层,每一层都呼叫它的下一层所提供的网络来完成自己的需求。

2.TCP协议和UDP协议

TCP协议建立在IP协议之上,TCP协议负责两台计算机之间建立连接,保证数据包按顺序到达,TCP协议会通过握手建立连接,然后对每个IP包编号,确保对方按顺序收到,就自动重发。

许多常用更高级的协议都是建立在TCP协议基础上,例如用于浏览器的HTTP协议,发送邮件的SMTP协议;

UDP协议通用建立在IP协议上,但是UDP协议买你想无连接的通信协议,不保证数据报的顺利到达,是不可靠传输,所以效率比TCP更高。

小结TCP与UDP的区别:

1.基于连接与无连接;
2.对系统资源的要求(TCP较多,UDP少);
3.UDP程序结构较简单;
4.流模式与数据报模式 ;
5.TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证。

3.Socket(套接字)

所谓套接字(Socket),就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制。从所处的地位来讲,套接字上联应用进程,下联网络协议栈,是应用程序通过网络协议进行通信的接口,是应用程序与网络协议根进行交互的接口。

Socket(套接字)可以看成是两个网络应用程序进行通信时,各自通信连接中的端点,这是一个逻辑上的概念。它是网络环境中进程间通信的API(应用程序编程接口),也是可以被命名和寻址的通信端点,使用中的每一个套接字都有其类型和一个与之相连进程。通信时其中一个网络应用程序将要传输的一段信息写入它所在主机的 Socket中,该 Socket通过与网络接口卡(NIC)相连的传输介质将这段信息送到另外一台主机的 Socket中,使对方能够接收到这段信息。 Socket是由IP地址和端口结合的,提供向应用层进程传送数据包的机制

4.TCP简单网络编程

案例:编写一个简单的TCP服务器程序,他接收客户端连接,把客户端发过来的字符串加上“hello”再重新发过去。

完整的TCP服务端程序如下:

python">import socket
import time
import threading  #导入threading线程模块
def tcplink(sock,addr):
    print('接受一个来自%s:%s连接请求'%addr)
    sock.send(b'welcome!')
    while True:
        data=sock.recv(1024)
        time.sleep(1)
        if not data or data.decode('utf-8')=='exit':
            break
        sock.send(('hello %s!'% data.decode('utf-8')).encode('utf-8'))
    sock.close()
    print('来自%s:%s连接关闭了.'%addr)
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind(('127.0.0.1',8888))
s.listen(5)
print('等待客户端连接....')
while True:
    sock,addr=s.accept()
    t=threading.Thread(target=tcplink,args=(sock,addr))
    t.start()

完整的TCP客户端程序

python">import socket
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(('127.0.0.1',8888))
print(s.recv(1024).decode('utf-8'))
for data in [b'Michael',b'Tracy',b'Sarah']:
    s.send(data)
    print(s.recv(1024).decode('utf-8'))
s.send(b'exit')
s.close()

1.先运行服务器端程序,运行结果如下:

在这里插入图片描述
2.在运行客户端程序建立连接,运行截图如下:
在这里插入图片描述
3.服务器端连接成功截图:
在这里插入图片描述

5.UDP简单网络编程

案例1:编写一个UDP服务器端程序,他接收客户端连接,把客户端发过来的坐标加1返回;

UDP服务器端程序

python">import socket
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
s.bind(('127.0.0.1',8888))  #绑定端口
print('Bind UDP on 8888')
while True:
    data,addr=s.recvfrom(1024)
    print('Received from %s:%s.'%addr)
    print('received:',data)
    p=data.decode('utf-8').split(",")#decode()解码,将字节串转换成字符串
    x=int(p[0])
    y=int(p[1])
    print(p[0],p[1])
    pos=str(x+1)+","+str(y+1)
    s.sendto(pos.encode('utf-8'),addr)

UDP客户端程序

python">import socket
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
x=input("请输入x坐标:")
y=input("请输入y坐标:")
data=str(x)+','+str(y)
s.sendto(data.encode('utf-8'),('127.0.0.1',8888))#encode()编码,将字符串转化为传送的字节串
data2,addr=s.recvfrom(1024)
print("接受服务器加1后坐标数据:",data2.decode('utf-8'))#decode解码
s.close()

运行结果展示:
1.先运行服务器端程序,运行结果如下:
在这里插入图片描述
2.再运行客户端程序,建立连接;运行结果如下:
在这里插入图片描述
输入你要输入的坐标,看返回的坐标都会加1;客户端运行结果如下:
在这里插入图片描述
服务器端运行结果如下:
在这里插入图片描述
案例2:编写一个简单的UDP服务器程序,他接收客户端连接,把客户端发来的名字加上“hello”再重新发过去。
例如:
input:鹏鹏写代码
out:hello 鹏鹏写代码

1.完整的UDP服务器端程序

python">import socket
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
s.bind(("127.0.0.1",6000))
print("UDP bound on port 6000")
while True:
     data,addr=s.recvfrom(1024)
     print("Receive from %s:%s"%addr)
     if data==b"exit":
         s.sendto(b"Good bye!]\n",addr)
         continue
     s.sendto(b"Hello %s!\n"%data,addr)

2.完整的UDP客户端程序

python">import socket
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
addr=('127.0.0.1',6000)

while True:
    data=input("please input your name:")
    if not data:
        continue
    s.sendto(data.encode(),addr)
    response,addr=s.recvfrom(1024)
    print(response.decode())
    if data=="exit":
        print("session is over from the server %s:%s\n"%addr)
        break
s.close()
  1. 运行展示
    (1) 先运行服务器端,截图如下:
    在这里插入图片描述
    (2)再运行客户端,截图如下:
    在这里插入图片描述
    (3)服务器端显示连接信息:
    在这里插入图片描述
    由于水平有限,欢迎各位大佬指正!

http://www.niftyadmin.cn/n/1870611.html

相关文章

基于 Spring Cloud 完整的微服务架构实战

本项目是一个基于 Spring Boot、Spring Cloud、Spring Oauth2 和 Spring Cloud Netflix 等框架构建的微服务项目。 技术栈 Spring boot - 微服务的入门级微框架,用来简化 Spring 应用的初始搭建以及开发过程。Eureka - 云端服务发现,一个基于 REST 的服…

python网络编程案例--基于TCP在线聊天程序

本程序主要通过在服务器端设计一个ServerUI类,封装接收消息的方法receiveMessage(self),发送消息sendMessage(self),并在构造函数中完成Tkinter界面布局。 在服务器端建立Socket并绑定5505后循环接收客户端的连接请求,当服务器与客户建立连接后&#xff…

pygame小游戏开发 - 五子棋

版权声明:原创不易,本文禁止抄袭、转载,侵权必究! 目录一、开发环境&需求分析二、功能模块三、游戏效果四、完整源码下载五、作者Info一、开发环境&需求分析 开发环境 :Windows10 Python3.6. 第三方库 &#…

C++ Error: range-based ‘for‘ loops are not allowed in C++98 mode

#include<iostream> using namespace std;//打开c标准库的头文件 int main() {int arr[10] {1,2,3,4,5,6,7,8,9,0}; //for(int i 0;i<10;i)//{//int j i1;//cout <<j<<endl;// cout <<arr[i]<<endl;// } for (int nVal : arr) //自动遍历a…

C++工程师学习笔记(一)

标准的C库中所有的组件都是被称为std的名字中声明和定义的。 在采用标准C的平台上使用标准的C库中的组件&#xff1a;using namespace std; 如果使用了名空间&#xff0c;则在使用#include编译预处理命令包含头文件时&#xff0c;必须去掉头文件的扩展名.h&#xff0c;导入头…

我们的微服务架构及Spring Cloud各个组件的概要

初识spring cloud 我们目前的架构 我们将来的架构 什么是Spring Boot Spring Boot简化了基于Spring的应用开发&#xff0c;通过少量的代码就能创建一个独立的、产品级别的Spring应用。 Spring Boot为Spring平台及第三方库提供开箱即用的设置&#xff0c;这样你就可以有条不紊地…

深入浅出数据分析宝典

数据分析真实项目流程明确问题&#xff1a;明确问题是数据分析的第一步&#xff0c;必须明确数据分析真实需求&#xff1b; 理解数据&#xff1a;数据获取和数据探索&#xff1b; 数据清洗&#xff1a;一个数据分析项目大部分时间花在数据清洗上&#xff1b; 数据分析和可视化&…

基于python的股票客户流失数据分析模型

目录 1.案例背景 2 2. 读取数据 2 3. 划分特征变量和目标变量 3 4. 模型的搭建和使用 3 5. 模型的使用 4 6. ROC曲线对模型的评估 7 7.总结 10 8.参考文献 10 9.致谢 10 1.案例背景 在进行一笔股票交易时候,交易者(股民)都要给其账户所在的证券公司支付一些手续费,虽然单笔…