好久没有更新博客了,最近在忙其他的事情,从今天开始继续每天的python学习,每天进步一点点!
废话不多说,直奔主题。
今日学习关键词:ip地址,端口,socket收发数据,echo服务器,聊天室
ip地址:哪怕是非计算机专业的同学们多多少少也会知道ip地址这个名词,那么它究竟是怎么构成的呢?
IP地址是指互联网协议地址(英语:Internet Protocol Address,又译为网际协议地址),是IP Address的缩写。IP地址是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。
那么什么是逻辑地址,什么又是物理地址?
逻辑地址(Logical Address) 是指由程序产生的与段相关的偏移地址部分。
物理地址(Physical Address) 是指出现在CPU外部地址总线上的寻址物理内存的地址信号,是地址变换的最终结果地址。
ip地址分A,B,C,D,E 5类,其中D,E两类基本不会用到
A类:将32位数据分为四部分,每一部分有8位,第一部分的最高位是0,其余7位是网络号,而后面三部分是主机号。
B类:将32位数据分为四部分,每一部分有8位,第一部分的最高两位是10,其余6位加上第二部分是网络号,后两部分是主机号。
C类:将32位数据分为四部分,每一部分有8位,第一部分的最高三位是110,其余5位加上二、三部分是网络号,最后一部分是主机号。
以上地址其实是ipv4的地址,因为ipv6用的不多,所以老师上课没有详细的去讲解。
端口是一个进程的代号,每一个程序运行都有自己特定的端口号,http为80,ftp为21
接下来直接上代码:
#发送数据
from socket import *
def main():
udpSocket = socket(AF_INET, SOCK_DGRAM) #创建一个套接字
udpAddr = ("192.168.78.142",6789) #通信的ip地址和端口
while True:
udpData = input("请输入发送的内容:").encode("gb2312")
udpSocket.sendto(udpData, udpAddr) #向指定的地址发送指定内容
if __name__ == "__main__":
main()
#接收数据
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()
接下来是模仿qq聊天:
#多线程模仿qq聊天
from threading import Thread
from socket import *
#定义一个接收数据的函数
def recvData():
while True:
#recvfrom(这里面的数字代表一个标识)
recvInfo = udpSocket.recvfrom(1024)
print("\n>>%s:%s" % (str(recvInfo[1]),recvInfo[0]))
print("\r<<",end="")
#定义一个发送数据的函数
def sendData():
while True:
sendInfo = input("\r<<")
#在这里采用encode进行编码,要和解码相匹配
udpSocket.sendto(sendInfo.encode("gb2312"),(destIp, destPort))
#线程可以共用全局变量,所以我们把要共用的数据写成全局变量的形式
udpSocket = None
destIp = ""
destPort = 0
def main():
global udpSocket
global destIp
global destPort
destIp = input("对方的ip:")
destPort = int(input("对方的端口:"))
udpSocket = socket(AF_INET, SOCK_DGRAM) #套接字
udpSocket.bind(("",4567)) #绑定端口
tr = Thread(target=recvData)
ts = Thread(target=sendData)
tr.start()
ts.start()
tr.join()
ts.join()
if __name__ == "__main__":
main()
上面的代码很简单的实现了进程间的通信。
这里补充一下,套接字后面的SOCK_DGRAM代表UDP协议,什么事UDP?
答:UDP 是User Datagram Protocol的简称, 中文名是用户数据报协议,是OSI(Open System Interconnection,开放式系统互联) 参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务
UDP简单直接但是稳定性不如TCP。如果是TCP协议应该吧SOCK_DGRAM换成SOCK_STREAM。
接着是下载了一个抓包软件wireshark,课上只是做了一些实验,由于没有环境就不测验了,以后肯定有机会会用到。
echo服务器意思就是发送之后对方就会给予一个回复,这个地方没有做重点讲,一带而过。