socket编程
一、网络通信要素
A:IP地址
(1) 用来标识网络上一台独立的主机
(2) IP地址 = 网络地址 + 主机地址(网络号:用于识别主机所在的网络/网段。主机号:用于识别该网络中的主机)
(3) 特殊的IP地址:127.0.0.1(本地回环地址、保留地址,点分十进制)可用于简单的测试网卡是否故障。表示本机。
B:端口号
(1) 用于标识进程的逻辑地址。不同的进程都有不同的端口标识。
(2) 端口:要将数据发送到对方指定的应用程序上,为了标识这些应用程序,所以给这些网络应用程序都用数字进行标识。为了方便称呼这些数字,则将这些数字 称为端口。(此端口是一个逻辑端口)
C: 传输协议:通讯的规则
例如:TCP、UDP协议(好比两个人得用同一种语言进行交流)
二、传输协议
1、UDP:User Datagram Protocol用户数据报协议
特点:
a、面向无连接:传输数据之前源端和目的端不需要建立连接;
b、每个数据报的大小都限制在64K(8个字节)以内;
c、面向报文的不可靠协议;(即:发送出去的数据不一定会接收得到)
d、传输速率快,效率高。
现实生活实例:
邮局寄件、实时在线聊天、视频会议…
2、TCP:Transmission Control Protocol传输控制协议
特点:
a、面向连接:传输数据之前需要建立连接;
b、在连接过程中进行大量数据传输;
c、通过“三次握手”的方式完成连接,是安全可靠协议;
d、传输速度慢,效率低。
三、socket通信流程
四、socket实现通信
server端
#!/usr/bin/env python # -*- coding:utf-8 -*- # author by lh import socket sk=socket.socket() address=('127.0.0.1',8000) sk.bind(address) # 绑定IP地址和端口 sk.listen(3) # 确定客户端能连几个人 while True: conn,add=sk.accept() # 阻塞,直到客户端有连接(如果收到的数据为空,则一直阻塞) while True: try: # 如果在客户端直接退出的情况下,保证下一个可以连接 da=conn.recv(1024) # 接收信息(必须是字符串类型) da=str(da,'utf8') print(da) if not da: # 判断是否收到的数据为空,为空则退出 break data=input('请输入聊天信息:') conn.send(bytes(data,'utf8')) # 发送信息(必须是bytes类型) except Exception: break sk.close()
client端
#!/usr/bin/env python # -*- coding:utf-8 -*- # author by lh import socket sk=socket.socket() address=('127.0.0.1',8000) sk.connect(address) # 创建连接 while True: data=input('请输入聊天信息:') if data=='q': break sk.send(bytes(data,'utf8')) # 发送信息(必须是bytes类型) da=sk.recv(1024) # 接收信息(必须是字符串类型) da=str(da,'utf8') print('收到的信息:',da) sk.close()
运行结果
server端 client端
五、socket实例
功能:实现命令在client端输入,传到server端,并且在server端执行并将运行结果(大文件)返回到客户端,防止粘包现象。
server端
#!/usr/bin/env python # -*- coding:utf-8 -*- # author by lh import subprocess import socket sk=socket.socket() address=('127.0.0.1',8000) sk.bind(address) # 绑定IP地址和端口 sk.listen(3) # 确定客户端能连几个人 while True: conn,add=sk.accept() # 阻塞,直到客户端有连接(如果收到的数据为空,则一直阻塞) while True: try: # 如果在客户端直接退出的情况下,保证下一个可以连接 da=conn.recv(1024) # 接收信息(必须是字符串类型) except Exception: break if not da: # 判断是否收到的数据为空,为空则退出 break print('命令为:',str(da,'utf8')) obj=subprocess.Popen(str(da,'utf8'),shell=True,stdout=subprocess.PIPE) cmd_result=obj.stdout.read() # 执行命令 result_len=bytes(str(len(cmd_result)),'utf8') # 计算执行结果的大小(将int类型转化为bytes类型) print('大小为:',result_len) conn.sendall(result_len) # 发送信息(必须是bytes类型) conn.sendall(cmd_result) # 发送执行结果 sk.close()
client端
#!/usr/bin/env python # -*- coding:utf-8 -*- # author by lh import socket sk=socket.socket() address=('127.0.0.1',8000) sk.connect(address) # 创建连接 while True: data=input('请输入命令:') if data=='q': break sk.send(bytes(data,'utf8')) # 发送信息(必须是bytes类型) result_len=int(str(sk.recv(1024),'utf8')) # 把收到的执行结果大小(bytes类型)转化为int类型 print('大小为:',result_len) data=bytes() # 创建一个空的bytes类型 while len(data)!=result_len: # 当长度和执行结果长度不相等时接收数据 recv=sk.recv(1024) # 接收数据 data+=recv #长度加每次传过来的长度 print('命令执行结果为:',str(data,'gbk')) sk.close()
posted on 2016-09-27 17:41 python屌丝的逆袭 阅读(127) 评论(0) 编辑 收藏 举报