```
import socket
import struct
# 创建udp套接字
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 绑定源IP地址
s.bind(('192.168.0.1', 0))
# 设置报文信息
data = 'hello world!'
dst_addr = ('192.168.0.2', 80)
# 修改源IP地址
src_addr = ('192.168.0.3', 0)
s.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton(src_addr[0]))
# 发送报文
s.sendto(data.encode('utf-8'), dst_addr)
```
1.新建文件tcp_server.py,用于模拟server端。import socket
tcpServer = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 创建socket对象,走tcp通道
host = socket.gethostname() # 获取本地主机名
port = 1000 # 端口号
addr = (host, port)
tcpServer.bind(addr) # 绑定地址
tcpServer.listen(5) # 设置最大连接数,超过后排队
while True:
conn,addr = tcpServer.accept() # 建立客户端连接
print(conn)
data = conn.recv(1024) # 接收来自客户端的数据,小于1024字节
print(data)
msg = 'Hello Client'.encode('utf-8')
conn.send(msg) # 发送数据给客户端
conn.close() # 关闭连接
本地主机名也可以换成IP地址,如host = '192.168.1.100'
server 端需要一直运行,等待 client 端的连接,所以使用while True无限循环
发送的数据必须是bytes类型,所以字符串需要编码'Hello Client'.encode('utf-8'),编码后为bytes类型
2.新建文件tcp_client.py,用于模拟client端。
import socket
tcpClient = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 创建socket对象
host = socket.gethostname()
port = 1000
addr = (host, port)
tcpClient.connect(addr) # 连接服务,指定主机和端口号
data = b'\x01\x64\xff' # 报文数据,bytes类型
tcpClient.send(data) # 发送数据给服务端
msg = tcpClient.recv(1024) # 接收来自服务端的数据,小于1024字节
print(msg.decode('utf-8'))
tcpClient.close()
client 端的地址需与 server 端一致,否则会报错:
IP地址不一致,则会发送数据给其他服务器,可能会出现报错TimeoutError
端口号不一致,会出现报错ConnectionRefusedError
3.打开两个cmd窗口,一个为server端窗口,另一个为client端窗口。
运行顺序,先启动server,后启动client:
server端窗口,先执行命令python tcp_server.py;client端窗口,后执行命令python tcp_client.py 。
socket(family,type[,protocal]) 使用给定的地址族、套接字类型、协议编号(默认为0)来创建套接字。
有效的端口号: 0~ 65535
但是小于1024的端口号基本上都预留给了操作系统
POSIX兼容系统(如Linux、Mac OS X等),在/etc/services文件中找到这些预留端口与的列表
面向连接的通信提供序列化、可靠的和不重复的数据交付,而没有记录边界。意味着每条消息都可以拆分多个片段,并且每个消息片段都能到达目的地,然后将它们按顺序组合在一起,最后将完整的信息传递给等待的应用程序。
实现方式(TCP):
传输控制协议(TCP), 创建TCP必须使用SOCK_STREAM作为套接字类型
因为这些套接字(AF_INET)的网络版本使用因特网协议(IP)来搜寻网络中的IP,
所以整个系统通常结合这两种协议(TCP/IP)来进行网络间数据通信。
数据报类型的套接字, 即在通信开始之前并不需要建议连接,当然也无法保证它的顺序性、可靠性或重复性
实现方式(UDP)
用户数据包协议(UDP), 创建UDP必须使用SOCK_DGRAM (datagram)作为套接字类型
它也使用因特网来寻找网络中主机,所以是UDP和IP的组合名字UDP/IP
注意点:
1)TCP发送数据时,已建立好TCP连接,所以不需要指定地址。UDP是面向无连接的,每次发送要指定是发给谁。
2)服务端与客户端不能直接发送列表,元组,字典。需要字符串化repr(data)。
TCP的优点: 可靠,稳定 TCP的可靠体现在TCP在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制,在数据传完后,还会断开连接用来节约系统资源。
TCP的缺点: 慢,效率低,占用系统资源高,易被攻击 TCP在传递数据之前,要先建连接,这会消耗时间,而且在数据传递时,确认机制、重传机制、拥塞控制机制等都会消耗大量的时间,而且要在每台设备上维护所有的传输连接,事实上,每个连接都会占用系统的CPU、内存等硬件资源。 而且,因为TCP有确认机制、三次握手机制,这些也导致TCP容易被人利用,实现DOS、DDOS、CC等攻击。
什么时候应该使用TCP : 当对网络通讯质量有要求的时候,比如:整个数据要准确无误的传递给对方,这往往用于一些要求可靠的应用,比如HTTP、HTTPS、FTP等传输文件的协议,POP、SMTP等邮件传输的协议。 在日常生活中,常见使用TCP协议的应用如下: 浏览器,用的HTTP FlashFXP,用的FTP Outlook,用的POP、SMTP Putty,用的Telnet、SSH QQ文件传输.
UDP的优点: 快,比TCP稍安全 UDP没有TCP的握手、确认、窗口、重传、拥塞控制等机制,UDP是一个无状态的传输协议,所以它在传递数据时非常快。没有TCP的这些机制,UDP较TCP被攻击者利用的漏洞就要少一些。但UDP也是无法避免攻击的,比如:UDP Flood攻击……
UDP的缺点: 不可靠,不稳定 因为UDP没有TCP那些可靠的机制,在数据传递时,如果网络质量不好,就会很容易丢包。
什么时候应该使用UDP: 当对网络通讯质量要求不高的时候,要求网络通讯速度能尽量的快,这时就可以使用UDP。 比如,日常生活中,常见使用UDP协议的应用如下: QQ语音 QQ视频 TFTP ……