1.什么是socket
socket是应用层与TCP/IP协议族通信的中间软件层,是一组接口。
用户在使用时,不需要操作具体的TCP协议的内容,用户只需要按照socket的要求操作,就能进行数据的发送和接收。
2.socket通信
3.socket方法
3.1socket实例化相关内容
1.socket实例化:
socket.socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None)
2.family():
socket.AF_UNIX:用于本地进程间通讯
socket.AF_INET:普遍使用这个,主要用于网络通信
3.type:
socket.SOCK_STREAM:用于TCP协议
socket.SOCK_DGRAM:用于UDP协议
4.proto=0忽略:
5.fileno=None忽略:
3.2服务端套接字函数
1.s.bind(("127.0.0.1",9999)):
绑定主机和端口到套接字
2.s.listen(5):
开始TCP监听。这里是开启5个监听连接,可允许5个客户端连接
3.s.accep():
等待客户端连接
3.3客户端套接字函数
1.s.connect():
连接服务端
2.s.connect_ex():
s.connect()函数的扩展版本,出错时返回出错编码,不抛出异常
"s.connect()"
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
import socket
socket_obj = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
data = socket_obj.connect(("127.0.0.1",9999))
print(data)
D:\software2\Python3\install\python.exe E:/PythonProject/new-python/python-test/BasicGrammer/test.py
Traceback (most recent call last):
File "E:/PythonProject/new-python/python-test/BasicGrammer/test.py", line 3, in <module>
data = socket_obj.connect(("127.0.0.1",9999))
ConnectionRefusedError: [WinError 10061] 由于目标计算机积极拒绝,无法连接。
Process finished with exit code 1
"s.connect_ex()"
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
import socket
socket_obj = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
data = socket_obj.connect_ex(("127.0.0.1",9999))
print(data)
D:\software2\Python3\install\python.exe E:/PythonProject/new-python/python-test/BasicGrammer/test.py
10061
Process finished with exit code 0
3.4公共用途的套接字函数
1.s.receive(1024):
结束多少字节的数据
2.s.send():
两次连着发送,数据会粘包,例如客户端send(3),send(4),连续两次send(),服务端接受recv(1024),就一次性把数据全都接收到了
send在待发送的数据字节数大于本端缓存区剩余空间时,数据丢失,不会发送完全
3.s.sendall():
发送完整的TCP数据,本质是循环调用send()
sendall在待发送数据字节数大于本端缓存区剩余空间时,数据不会丢失,循环调用send()直到发送完成
4.s.recvfrom():
back_msg,addr = udp_server_client.recvfrom(BUFSIZE)
会接收数据和对方的地址
5.s.close():
关闭连接
4.socket实例
4.1基本socket例子
"server.py"
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
import socket
sock_obj = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock_obj.bind(("127.0.0.1",9999))
sock_obj.listen(5)
conn,client_addr = sock_obj.accept()
print(type(conn),client_addr)
data = conn.recv(1024)
print(type(data))
conn.sendall(data)
"client.py"
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
import socket
socket_obj = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
socket_obj.connect_ex(("127.0.0.1",9999))
# 这里要发送bytes类型数据
socket_obj.send("hello".encode("utf-8"))
data = socket_obj.recv(1024)
print(data.decode("utf-8"))
4.2循环接收
"server"
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
import socket
sock_obj = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock_obj.bind(("127.0.0.1",9999))
sock_obj.listen(5)
conn,client_addr = sock_obj.accept()
print(type(conn),client_addr)
while True:
data = conn.recv(1024)
if not data:
break
print(type(data))
conn.sendall(data)
"client"
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
import socket
socket_obj = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
socket_obj.connect_ex(("127.0.0.1",9999))
while True:
data = input("please input data:").strip()
if not data:
continue #客户端发空消息时,服务端是接受不到的,就卡在那里,客户端也等不到服务端的回复,所以客户端也卡主了
# 这里要发送bytes类型数据
socket_obj.send(data.encode("utf-8"))
data = socket_obj.recv(1024)
print(data.decode("utf-8"))
4.5简单的单人聊天程序
"server"
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
import socket
sock_obj = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock_obj.bind(("127.0.0.1",9999))
sock_obj.listen(5)
conn,client_addr = sock_obj.accept()
print(type(conn),client_addr)
while True:
data = conn.recv(1024)
if not data:
break
print("receive:",data.decode("utf-8"))
send_data = input("plese send your data:").strip()
conn.sendall(send_data.encode("utf-8"))
"client"
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
import socket
socket_obj = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
socket_obj.connect_ex(("127.0.0.1",9999))
while True:
data = input("please input data:").strip()
if not data:
continue
# 这里要发送bytes类型数据
socket_obj.send(data.encode("utf-8"))
data = socket_obj.recv(1024)
print(data.decode("utf-8"))
4.6多人聊天
上面只允许一个连接,如果客户端断开连接,服务端也同时退出了
只因为服务端if not data: break,接收不到数据,就跳出循环了。
"一个人断开连接后,还允许其他人连接"
"server"
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
import socket
sock_obj = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock_obj.bind(("127.0.0.1",9999))
sock_obj.listen(5)
while True:
conn,client_addr = sock_obj.accept()# 阻塞直到有链接,有了连接后,就会为请求生成一个连接对象
print(type(conn),client_addr)
while True:
try:
data = conn.recv(1024)
if not data:
print("not data")
break #适用于linux操作系统,如果客户端断开,Linux系统是陷入死循环
print("receive:",data.decode("utf-8"))
conn.sendall(data)
except Exception as e: #适用于windows操作系统,如果客户端断开,windows系统是报异常
break
"client"
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
import socket
socket_obj = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
socket_obj.connect_ex(("127.0.0.1",9999))
while True:
data = input("please input data:").strip()
if not data:
continue
# 这里要发送bytes类型数据
socket_obj.send(data.encode("utf-8"))
data = socket_obj.recv(1024)
print(data.decode("utf-8"))
4.7udp案例
"server"
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
import socket
sock_obj = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
sock_obj.bind(("127.0.0.1",9999))
data,client_addr =sock_obj.recvfrom(1024)
print(data,client_addr)
sock_obj.sendto(data.upper(),client_addr)
"client"
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
import socket
socket_obj = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
socket_obj.sendto("hello".encode("utf-8"),("127.0.0.1",9999))
data,server_addr =socket_obj.recvfrom(1024)
print(data,server_addr)
4.8TCP and UDP
"tcp基于链接通信"
1.基于链接,则需要listen(backlog),指定连接池的大小
2.基于链接,必须先运行的服务端,然后客户端发起链接请求
3.对于mac系统:如果一端断开了链接,那另外一端的链接也跟着完蛋recv将不会阻塞,收到的是空(解决方法是:服务端在收消息后加上if判断,空消息就break掉通信循环)
4.对于windows/linux系统:如果一端断开了链接,那另外一端的链接也跟着完蛋recv将不会阻塞,收到的是空(解决方法是:服务端通信循环内加异常处理,捕捉到异常后就break掉通讯循环)
udp无链接
1.无链接,因而无需listen(backlog),更加没有什么连接池之说了
2.无链接,udp的sendinto不用管是否有一个正在运行的服务端,可以己端一个劲的发消息,只不过数据丢失
3.recvfrom收的数据小于sendinto发送的数据时,在mac和linux系统上数据直接丢失,在windows系统上发送的比接收的大直接报错
只有sendinto发送数据没有recvfrom收数据,数据丢失
5.粘包
5.1粘包问题-ssh命令
"server"
import socket
import subprocess
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
phone.bind(('127.0.0.1',9901)) #0-65535:0-1024给操作系统使用
phone.listen(5)
print('starting...')
while True: # 链接循环
conn,client_addr=phone.accept()
print(client_addr)
while True: #通信循环
try:
#1、收命令
cmd=conn.recv(1024)
if not cmd:break #适用于linux操作系统
#2、执行命令,拿到结果
obj = subprocess.Popen(cmd.decode('utf-8'), shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout=obj.stdout.read()
stderr=obj.stderr.read()
#3、把命令的结果返回给客户端
print(len(stdout)+len(stderr))
conn.send(stdout+stderr) #+是一个可以优化的点
except ConnectionResetError: #适用于windows操作系统
break
conn.close()
phone.close()
D:\software2\Python3\install\python.exe E:/PythonProject/new-python/python-test/BasicGrammer/server.py
starting...
('127.0.0.1', 12105)
13652
617
617
617
617
617
617
617
617
617
617
617
617
617
617
617
"client"
import socket
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect(('127.0.0.1',9901))
while True:
#1、发命令
cmd=input('>>: ').strip() #ls /etc
if not cmd:continue
phone.send(cmd.encode('utf-8'))
#2、拿命令的结果,并打印
data=phone.recv(1024) #1024是一个坑
print(data.decode('gbk')) #Windows系统默认是gbk编码,linux上是"utf-8"
phone.close()
D:\software2\Python3\install\python.exe E:/PythonProject/new-python/python-test/BasicGrammer/client.py
>>: tasklist
映像名称 PID 会话名 会话# 内存使用
========================= ======== ================ =========== ============
System Idle Process 0 Services 0 8 K
System 4 Services 0 152 K
Registry 96 Services 0 73,504 K
smss.exe 352 Services 0 1,060 K
csrss.exe 552 Services 0 4,676 K
wininit.exe 652 Services 0 5,892 K
csrss.exe 660 Console 1 6,924 K
services.exe 724 Services 0 8,712 K
lsass.exe 732 Services 0 13,724 K
svchost.exe 844 Services 0 3,696 K
svchost.exe 868 Services 0 23,876 K
fontdrvh
>>: dir
ost.exe 892 Services 0 3,140 K
WUDFHost.exe 900 Services 0 7,440 K
svchost.exe 992 Services 0 14,372 K
svchost.exe 388 Services 0 7,624 K
WUDFHost.exe 416 Services 0 12,160 K
winlogon.exe 1056 Console 1 11,484 K
fontdrvhost.exe 1144 Console 1 26,136 K
dwm.exe 1216 Console 1 80,596 K
svchost.exe 1280 Services 0 10,392 K
svchost.exe 1288 Services 0 6,676 K
svchost.exe 1372 Services 0 9,684 K
svchost.exe 1384 Services 0 11,404 K
svchost.exe 1480 Services 0 8,932 K
svchost.exe
>>: dir
1564 Services 0 12,840 K
svchost.exe 1716 Services 0 6,812 K
NVDisplay.Container.exe 1752 Services 0 10,664 K
svchost.exe 1844 Services 0 8,616 K
svchost.exe 1884 Services 0 5,404 K
svchost.exe 1952 Services 0 11,364 K
svchost.exe 2000 Services 0 7,696 K
svchost.exe 2024 Services 0 10,348 K
svchost.exe 2036 Services 0 7,472 K
svchost.exe 1156 Services 0 12,260 K
svchost.exe 1808 Services 0 5,468 K
Memory Compression 2176 Services 0 678,716 K
svchost.exe 2256 Services 0 9,008 K
svchost.exe
>>: dir
2264 Services 0 9,488 K
svchost.exe 2324 Services 0 13,624 K
igfxCUIService.exe 2368 Services 0 6,844 K
svchost.exe 2448 Services 0 11,796 K
svchost.exe 2524 Services 0 7,168 K
svchost.exe 2544 Services 0 11,160 K
svchost.exe 2636 Services 0 8,528 K
svchost.exe 2784 Services 0 11,636 K
svchost.exe 2796 Services 0 8,360 K
svchost.exe 2912 Services 0 5,720 K
svchost.exe 2956 Services 0 5,896 K
svchost.exe 2964 Services 0 11,452 K
360rps.exe 2976 Services 0 6,112 K
ZhuDongFangYu.exe 3000 Ser
>>: dir
vices 0 20,540 K
svchost.exe 3240 Services 0 13,816 K
svchost.exe 3304 Services 0 11,572 K
spoolsv.exe 3412 Services 0 11,976 K
svchost.exe 3480 Services 0 13,736 K
svchost.exe 3516 Services 0 7,908 K
wlanext.exe 3544 Services 0 14,340 K
conhost.exe 3572 Services 0 4,588 K
svchost.exe 3788 Services 0 7,476 K
svchost.exe 3796 Services 0 6,588 K
IntelCpHDCPSvc.exe 3940 Services 0 5,936 K
svchost.exe 3948 Services 0 12,208 K
esif_uf.exe 3960 Services 0 5,908 K
EvtEng.exe 3972 Services
>>: dir
0 12,148 K
svchost.exe 3188 Services 0 21,512 K
QQProtect.exe 3368 Services 0 18,352 K
svchost.exe 3596 Services 0 6,156 K
svchost.exe 3576 Services 0 16,480 K
ibtsiva.exe 3920 Services 0 4,104 K
svchost.exe 4108 Services 0 16,284 K
tvnserver.exe 4116 Services 0 6,828 K
ICEsoundService64.exe 4124 Services 0 5,352 K
RegSrvc.exe 4132 Services 0 7,640 K
ZeroConfigService.exe 4148 Services 0 15,504 K
vmnat.exe 4140 Services 0 6,388 K
FNPLicensingService.exe 4160 Services 0 9,100 K
vmnetdhcp.exe 4168 Services
>>: dir
0 4,504 K
IntelCpHeciSvc.exe 4232 Services 0 8,384 K
svchost.exe 4244 Services 0 8,304 K
vmware-authd.exe 4280 Services 0 10,104 K
vmware-usbarbitrator64.ex 4292 Services 0 8,944 K
svchost.exe 4308 Services 0 11,484 K
svchost.exe 4412 Services 0 11,332 K
unsecapp.exe 5212 Services 0 6,424 K
WmiPrvSE.exe 5596 Services 0 12,280 K
NVDisplay.Container.exe 6068 Console 1 23,456 K
esif_assist_64.exe 6048 Console 1 3,436 K
sihost.exe 5868 Console 1 24,228 K
svchost.exe 6156 Console 1 19,520 K
PresentationFontCache.exe 6204 Services 0
>>: dir
19,676 K
svchost.exe 6212 Console 1 30,216 K
svchost.exe 6364 Services 0 13,028 K
taskhostw.exe 6428 Console 1 15,552 K
svchost.exe 6560 Services 0 16,736 K
svchost.exe 6576 Services 0 6,696 K
explorer.exe 6628 Console 1 161,144 K
ctfmon.exe 6672 Console 1 25,300 K
igfxEM.exe 6996 Console 1 10,920 K
ChsIME.exe 6256 Console 1 6,756 K
svchost.exe 6952 Console 1 16,488 K
ShellExperienceHost.exe 7180 Console 1 70,040 K
SearchUI.exe 7352 Console 1 93,568 K
RuntimeBroker.exe 7444 Console 1 26,628 K
>>: dir
RuntimeBroker.exe 7520 Console 1 26,296 K
WindowsInternal.Composabl 7932 Console 1 42,872 K
RuntimeBroker.exe 8144 Console 1 12,312 K
360sd.exe 5736 Console 1 4,044 K
360rp.exe 2820 Console 1 27,900 K
360tray.exe 4000 Console 1 104,624 K
vmware-tray.exe 9184 Console 1 7,732 K
RAVBg64.exe 8932 Console 1 980 K
RAVCpl64.exe 7372 Console 1 1,096 K
svchost.exe 2072 Services 0 20,852 K
svchost.exe 8880 Services 0 7,868 K
SgrmBroker.exe 8380 Services 0 6,072 K
svchost.exe 1744 Services 0 9,376 K
svchost.ex
>>: dir
e 2140 Console 1 16,856 K
svchost.exe 4380 Services 0 8,108 K
svchost.exe 1924 Services 0 8,452 K
SogouCloud.exe 968 Console 1 24,448 K
svchost.exe 1832 Services 0 5,336 K
360bdoctor.exe 6064 Console 1 11,320 K
smartscreen.exe 9016 Console 1 20,440 K
QQ.exe 1824 Console 1 177,736 K
TXPlatform.exe 4668 Console 1 2,764 K
chrome.exe 2352 Console 1 180,568 K
chrome.exe 7492 Console 1 7,852 K
chrome.exe 5512 Console 1 8,300 K
chrome.exe 8520 Console 1 181,680 K
chrome.exe
>>: dir
2076 Console 1 31,268 K
chrome.exe 2516 Console 1 53,712 K
SystemSettingsBroker.exe 3452 Console 1 14,440 K
chrome.exe 4844 Console 1 118,804 K
SogouImeBroker.exe 1516 Console 1 6,668 K
dllhost.exe 2008 Console 1 9,556 K
WeChat.exe 10532 Console 1 123,036 K
WeChatWeb.exe 11144 Console 1 18,492 K
*.exe 4852 Console 1 14,556 K
*.exe 9432 Console 1 84,104 K
sysproxy-cmd.exe 8548 Console 1 4,600 K
wps.exe 9660 Console 1 47,504 K
wps.exe 9200 Console 1 83,356 K
wps.exe 1
>>: dir
0896 Console 1 20,800 K
WmiPrvSE.exe 4932 Services 0 13,888 K
wpscenter.exe 10876 Console 1 61,264 K
wps.exe 7616 Console 1 21,304 K
pycharm64.exe 11200 Console 1 1,043,416 K
fsnotifier64.exe 9800 Console 1 1,832 K
conhost.exe 10772 Console 1 4,828 K
svchost.exe 6584 Services 0 16,908 K
svchost.exe 7600 Services 0 8,928 K
winpty-agent.exe 12384 Console 1 5,044 K
conhost.exe 13828 Console 1 7,336 K
cmd.exe 11196 Console 1 3,268 K
ThunderPlatform.exe 9336 Console 1 25,444 K
chrome.exe 12948 Conso
>>: dir
le 1 45,764 K
Pic_2345Svc.exe 1008 Services 0 18,108 K
chrome.exe 6572 Console 1 150,296 K
chrome.exe 13956 Console 1 51,216 K
chrome.exe 5812 Console 1 16,192 K
svchost.exe 2804 Services 0 7,064 K
svchost.exe 7876 Services 0 5,108 K
winpty-agent.exe 13912 Console 1 5,204 K
conhost.exe 14352 Console 1 7,504 K
cmd.exe 2136 Console 1 3,432 K
python.exe 4536 Console 1 11,008 K
conhost.exe 10664 Console 1 10,924 K
python.exe 14976 Console 1 9,996 K
conhost.exe 2844 Console
>>: dir
1 10,916 K
dllhost.exe 13024 Console 1 6,816 K
dllhost.exe 15024 Console 1 8,236 K
cmd.exe 4272 Console 1 3,752 K
tasklist.exe 4224 Console 1 7,536 K
驱动器 E 中的卷没有标签。
卷的序列号是 CE9C-6DD5
E:\PythonProject\new-python\python-test\BasicGrammer 的目录
2019/05/19 周日 12:14 <DIR> .
2019/05/19 周日 12:14 <DIR> ..
2019/05/19 周日 12:12 <DIR> .idea
2019/05/19 周日 12:14 387 client.py
2019/05/17 周五 16:53 941 guessage.py
2019/05/19 周日 12:11 1,130 server.py
2019/05/19 周日 10:49 86 test.py
2019/05/17 周五 16:53 88,888 猜年龄的游戏.jpg
5 个文件 91,432 字节
3 个目录 71,271,063,552 可用字节
驱动器 E 中的卷没有标签。
卷的序列号是 CE9C-6DD5
E:\PythonPr
>>: dir
oject\new-python\python-test\BasicGrammer 的目录
2019/05/19 周日 12:14 <DIR> .
2019/05/19 周日 12:14 <DIR> ..
2019/05/19 周日 12:12 <DIR> .idea
2019/05/19 周日 12:14 387 client.py
2019/05/17 周五 16:53 941 guessage.py
2019/05/19 周日 12:11 1,130 server.py
2019/05/19 周日 10:49 86 test.py
2019/05/17 周五 16:53 88,888 猜年龄的游戏.jpg
5 个文件 91,432 字节
3 个目录 71,271,063,552 可用字节
驱动器 E 中的卷没有标签。
卷的序列号是 CE9C-6DD5
E:\PythonProject\new-python\python-test\BasicGrammer 的目录
2019/05/19 周日 12:14 <DIR> .
2019/05/19 周日 12:14 <DIR> ..
2019/05/19 周日 12:12 <DIR> .idea
2019/05/19 周日 12:14 387 client.py
2019/05/17 周五 16:53 941 guessage.py
2019/05/19 周日 12:11 1,130 server.py
2019/05/19 周日 10:49 86 test.py
2019/05/17
>>: dir
周五 16:53 88,888 猜年龄的游戏.jpg
5 个文件 91,432 字节
3 个目录 71,271,063,552 可用字节
驱动器 E 中的卷没有标签。
卷的序列号是 CE9C-6DD5
E:\PythonProject\new-python\python-test\BasicGrammer 的目录
2019/05/19 周日 12:14 <DIR> .
2019/05/19 周日 12:14 <DIR> ..
2019/05/19 周日 12:12 <DIR> .idea
2019/05/19 周日 12:14 387 client.py
2019/05/17 周五 16:53 941 guessage.py
2019/05/19 周日 12:11 1,130 server.py
2019/05/19 周日 10:49 86 test.py
2019/05/17 周五 16:53 88,888 猜年龄的游戏.jpg
5 个文件 91,432 字节
3 个目录 71,271,063,552 可用字节
驱动器 E 中的卷没有标签。
卷的序列号是 CE9C-6DD5
E:\PythonProject\new-python\python-test\BasicGrammer 的目录
2019/05/19 周日 12:14 <DIR> .
2019/05/19 周日 12:14 <DIR> ..
2019/05/19 周日 12:12 <DIR> .idea
2019/05/
>>:
从上面的实验,我们可以看到执行完tasklist后,在执行dir,拿到的结果还是tasklist的内容,多次之后才拿到dir的结果
但是我们重新操作,执行dir命令,还是能够正确拿到结果的
为什么呢?
这就是粘包现象,tasklist命令的结果是13652字节,大于客户端的recv(1024),所以剩下的数据就放在了服务端缓存中,等客户端下次recv()时,再继续发送缓存的内容
本该第一次就发送完成的数据,却在第二次,第三次才发送过去,两次结果混合在了一起,这就是粘包