很久之前Python就业班就已经学过了,昨天回头看朋友的面经发现他面试的过程被问到这方便的问题,回头想想记忆有点模糊了,重写一篇博客重点复习下Socket通信。
什么是socket
创建socket
在Python中使用socket模块的函数socket就可以完成
代码语言:javascript复制socket.socket(AddressFamily,Type)
创建TCP Socket
创建tcp套接字
代码语言:javascript复制import socket
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
创建UDP Socket
创建udp套接字
代码语言:javascript复制import socket
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
UDP网络程序
准备一台虚拟机和本机,进行通信。
本机Mac ip:10.211.55.2
虚拟机Centos ip:10.211.55.23
UDP发送数据
代码语言:javascript复制from socket import *
from django.dispatch import receiver
#1、创建套接字
udpSocket = socket(AF_INET,SOCK_DGRAM)
#2、接收方地址,端口
sendAddr = ('10.211.55.23',8888)
#3、要发送的数据
sendData = input("输入要发送的数据:")
#4、发送数据到指定接收方
udpSocket.sendto(sendData.encode('utf-8'),sendAddr)
#7、关闭套接字
udpSocket.close()
虚拟机直接用nc进行监听来接收数据
UDP发送 接收数据
代码语言:javascript复制from socket import *
from django.dispatch import receiver
#1、创建套接字
udpSocket = socket(AF_INET,SOCK_DGRAM)
#2、接收方地址,端口
sendAddr = ('10.211.55.23',8888)
#3、要发送的数据
sendData = input("输入要发送的数据:")
#4、发送数据到指定接收方
udpSocket.sendto(sendData.encode('utf-8'),sendAddr)
#5、等待对方发送数据
recvData = udpSocket.recvfrom(1024) #1024最大可接收的字节
#6、显示对方发送的数据
print(recvData)
#7、关闭套接字
udpSocket.close()
hacker是我本机Mac发送到CentOs的数据
1 是CentOs回本机Mac的数据
UDP端口绑定 接收数据
上面的发送 接收数据代码其实并不是很完善
接收数据应该有一个绑定端口的过程
发送方不需要绑定端口,接收方(服务方)一定要绑定,不然发送方是很难找到我们并发送数据给我们的
代码语言:javascript复制bindAddr = ('',7788)#ip地址和端口号,ip一般不写,表示本机的任何一个ip
udpSocket.bind(bindAddr)
ip一般不写,表示任何一个ip都是可以的
代码语言:javascript复制from socket import *
#1、创建套接字
udpSocket = socket(AF_INET,SOCK_DGRAM)
#2、绑定端口
bindAddr = ("",7788)
udpSocket.bind(bindAddr)
#3、sendto发送数据,revfrom接收数据,1024表示接收的最大字节数
recvData = udpSocket.recvfrom(1024)
content,destInfo = recvData
print("content is %s"%content)
print("content is %s"%content.decode("utf-8"))
#4、关闭套接字
udpSocket.close()
简单聊天室
代码语言:javascript复制from socket import *
def main():
udpSocket = socket(AF_INET,SOCK_DGRAM)
udpSocket.bind(("",6789))
#收,打印
while True:
recvInfor = udpSocket.recvfrom(1024)
print("[%s]:%s"%(str(recvInfor[1]),recvInfor[0].decode("gb2312")))
if __name__ == "__main__":
main()
echo服务器
echo服务器 简单说就是,你给我发一个东西我给你回一个。
比咱们上面的程序就多了一句话。
代码语言:javascript复制from socket import *
def main():
udpSocket = socket(AF_INET,SOCK_DGRAM)
bindAddr = ('',7788)
udpSocket.bind(bindAddr)
num = 1
while True:
#等待接收对方发送的数据
recvData = udpSocket.recvfrom(1024)
#接收的数据在发给对方,recvData[0]是数据内容,recvData[1]是ip端口信息
udpSocket.sendto(recvData[0],recvData[1])
print("[%s]:%s"%(str(recvData[1]),recvData[0].decode("gb2312")))
if __name__ == "__main__":
main()
可见我们发送完数据以后能成功返回来。
模拟QQ聊天(多线程)
代码语言:javascript复制from threading import Thread
from socket import *
#1、收数据,后打印
def recvData():
while True:
recvInfo = udpSocket.recvfrom(1024)
#recvInfo[1]是ip端口数据,recvInfo[0]是内容
print(">>%s:%s"%(str(recvInfo[1]),recvInfo[0].decode("gb2312")))
#2、检测键盘发数据
def sendData():
while True:
sendInfo = input("<<")
udpSocket.sendto(sendInfo.encode("gb2312"),(destIp,destPort))
udpSocket = None
destIp = ""
destPort = 0
def main():
#声明全局变量
global udpSocket
global destIp
global destPort
udpSocket = socket(AF_INET,SOCK_DGRAM)
udpSocket.bind(("",4567))
destIp = input("对方的ip")
destPort = int(input("对方的端口"))
#两个线程
tr = Thread(target=recvData)
ts = Thread(target=sendData)
tr.start()
ts.start()
tr.join()#等待tr进程结束以后往下走
ts.join()
if __name__ == "__main__":
main()