远程管理软件和黑客软件大多依赖于Socket来实现特定功能,前几年流行的端口反弹更是把这项技术发挥到了极致。

  如前所述,UDP和TCP是网络体系结构的传输层运行的两大重要协议,其中,TCP适用于对效率要求相对低而准确性要求相对高的场合,如文本传输、电子邮件等;而UDP适用于对效率要求相对高,对准确性要求相对低的场合,如视频在线点播、网络语音通话等。在Python中,主要使用socket模块来支持TCP和UDP编程。

  9.2.1 UDP编程

  在很多年以前普通家庭还没有手机、电话、传呼机的时候,主要靠信件往来联系,发信人提哦啊好收信人地址然后把信件寄出去就可以了,但是没法保证对方一定能收到这封信(例如对方换了地址),也不能保证不同时间的几封信按照发出的顺序到达目的地。UDP的工作过程就类似于邮寄普通信件,它属于无连接协议,在UDP编程时不需要首先建立连接,而是直接向接收方发送信息。UDP也不提供应答和重传机制,无法保证数据一定鞥能够到达目的地。UDP最大的优点是效率高,其首部中只包含双发地址于校验等很少的字段,额外开销很小。UDP编程经常用到的socket模块方法如下。

  (1)socket([family[,type[,proto]]] :创建一个Socket对象,其中family为socket.AF_INET表示IPv4,AF_INET6表示IPv6;type为SOCK_STREAM表示使用TCP,SOCK_DGRAM表示使用UDP。

  (2)sendto(string,address):把string指定的内容发送给address指定的地址,其中address是一个包含接收方主机IP地址的应用进程端号的元组,格式为(IP地址,端口号)。

  (3)recvfrom(bufsize[,flags]):接收数据。

  下面通过一个示例来简单了解一个如何使用UDP进行网络通信。

  发送端发送一个字符串,假设接收端在本机5000端口进行监听,并显示接受的内容,如果收到字符串'bye'(忽略大小写)则结束监听。

  接收端代码:

 import socket

 #使用IPv4协议,使用UDP传输数据
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) #绑定端口和端口好,空字符串表示本机任何可用IP地址
s.bind('',5000) while True:
data,addr = s.recvfrom(1024) #显示接收到的内容
print('received message:{0} from PORT{1} on {2}'.format(data.decode(),addr[1],addr[0])) if data.decode().lower() == 'bye':
break s.close()

  发送端代码:

import socket
import sys s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) #假设192.168.1.103是接收端机器的IP地址
s.sendto(sys.argv[1].encode(),('192.168.1.103',5000)) s.close()

  将上面的代码分别保存为receiver.py和sender.py,然后首先启动一个命令提示符环境并运行接收端程序,这时接收端程序处于阻塞状态,接下来再启动一个新的命令体书法环境并运行发送端程序,此时会看到接收端程序继续运行并显示接收到的内容以及发送端程序所在计算机IP地址和占用的端口号。当发送端发送字符串'bye'后,接收单程序结束,此后再次运行发送端程序时接收端没有任何反应,但发送端程序也并不报错。这就是UDP的特点,即“尽最大努力传输”,并不能保证非常好的服务质量。

  可以使用下面的Python代码来获取本机的IP地址和网卡的物理地址。

 ip = socket.gethostbyname(socket.gethostname())  #本机IP地址
node = uuid.getnode()
print('node:',node) macHex = uuid.UUID(int=node).hex[-12:]
mac = []
print(macHex)
for i in range(len(macHex))[::2]:
mac.append(macHex[i:i+2]) mac1 = ':'.join(mac) #网卡的物理地址 print('IP:',ip)
print('MAC:',mac1)

  拓展知识:发送数据时,如果目标IP地址中最后一组数字是255,表示广播地址,也就是说局域网内的所有主机都会受到信息。

  9.2.2 TCP 编程

  TCP一般用于要求可靠数据传输的场合。编写TCP程序是需要用到的socket模块方法主要如下。

  (1)connect(address):连接远程计算机。

  (2)send(bytes[,flags]):发送数据。

  (3)recv(bufsize[,flags]):接收数据。

  (4)bind(address):绑定地址。

  (5)listen(backlog):开始监听,等待客户端连接。

  (6)accept():响应客户端的请求,接收一个连接。

  下面通过一个示例来演示如何使用TCP进行通信。会聊天的小机器人。

  使用TCP进行铜线需要首先在客户端和服务端之间建立连接,并且要在通信结束后关闭连接以释放资源。TCP能够提供比UDP更好的服务质量,通信可靠性有本质上的提高。下面的代码简单模拟了机器人聊天软件原理,服务端提前建立好字典,可以根据收到的内容自动回复。

  服务端代码:

 import socket

 words = {'how are you?':'Fine,thank you','how old are you?':'','what is your name?':'Dong FuGuo',"what's your name?":'DongFuGuo',
'where do you work?':'SDIBT','bye':'BYE'} HOST = ''
PORT=50007
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#绑定socket
s.bind((HOST,PORT)) #开始监听一个客户端连接
s.listen(1)
print('Listening at port:',PORT)
conn,addr = s.accept() print('Connected by',addr) while True:
data = conn.recv(1024)
data = data.decode()
if not data:
break print('Received message:',data)
conn.sendall(words.get(data,'Nothing').encode())
conn.close()
s.close()

  客户端代码:

 import socket, sys

 # 服务端主机的IP地址和端口好
HOST = '192.168.1.101'
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
# 连接服务器
s.connect((HOST, PORT))
except Exception as e:
print('Server not found or not open')
sys.exit() while True:
c = input('Input the content you want to send:')
# 发送数据
s.sendall(c.encode()) # 从服务器端接收数据
data = s.recv(1024)
print('Received:', data)
if c.lower() == 'bye':
break # 关闭连接
s.close()

  扩展知识:Python标准库socket处理支持UDP和TCP编程之外,还提供了用来获取本地主机名的gethostname()、根据主机名获取IP地址的gethostbyname()、根据IP地址获取主机名的gethostbyaddr()、根据端口号获取对应服务名称的getservbyport()、根据服务名称获取对应端口号的getservbyname()等方法。

最新文章

  1. Windows下搭建Spark+Hadoop开发环境
  2. poj1417 带权并查集 + 背包 + 记录路径
  3. velocity思维导图笔记
  4. 【HDOJ】3466 Proud Merchants
  5. C++的精髓——虚函数
  6. Android.mk与jni目录的关系
  7. hdu 2865 Polya计数+(矩阵 or 找规律 求C)
  8. mybatis在xml文件中处理转义字符
  9. ios 传递JSON串过去 前面多了个等号
  10. bootstrap-paginator分页示例 源码 MVC
  11. SpringMVC 图片上传,检查图片大小
  12. 关于echarts图表在tab页中width:100%失效的问题
  13. Eclipse中安装springmvc插件
  14. 转载 c# automapper 使用(一) https://www.cnblogs.com/caoyc/p/6367828.html
  15. Memcached遇到的问题及解决办法
  16. Centos7 搭建lnmp环境 (centos7+nginx+MySQL5.7.9+PHP7)
  17. Elasticsearch之启动(前台和后台)
  18. iPhone调用ffmpeg2.0.2解码h264视频的示例代码
  19. 【JavaScript】动态原型模式创建对象 ||为何不能用字面量创建原型对象?
  20. Tomcat应用配置

热门文章

  1. 初识bigdata时的一些技能小贴士
  2. 【数学】mex是什么
  3. E: Unable to lock the administration directory (/var/lib/dpkg/)
  4. WPF,Silverlight与XAML读书笔记(3) - 标记扩展
  5. Python猜年龄
  6. 如何在vue项目中引入阿里巴巴的iconfont图库
  7. Redis学习和应用记录(1)--介绍和安装
  8. 在网页上打印,js window.print
  9. [Swift通天遁地]七、数据与安全-(16)检测Apple设备是否越狱
  10. [Swift通天遁地]八、媒体与动画-(4)给相机添加CoreImage滤镜效果