今天看的内容有限,感觉前面没有看Linux和底层基础知识有点吃亏,不过今天已经把报告整出来了,再也不用为这个东西恼火了
一、关于socket收发消息的原理
首先关于计算机,分为三层:应用软件——操作系统(OS)——硬件(特指内存)
内存又被分为:内核区(存放操作系统,用于收发指令代替你去操作硬件,例如:网卡)
用户区:各种存放的应用程序
socket在执行recv和send的时候,其本质是想内核区发送或者接受,再由os去操作系统通过网卡进行信息的传递交互
所以这个在实际中机会又下面这个问题:
首先是客户端和服务端的代码:
#服务端
importsocket
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.bind(('127.0.1.11',8000)) #注意,地址和端口是以一个元组的形式给入
phone.listen(5)print('waiting!!!')
conn,addr=phone.accept()print('oking')
msg= conn.recv(1024)print(msg)
conn.send(msg.upper())
conn.close()
phone.close()#客户端
importsocket
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect(('127.0.1.11',8000))
phone.send('hello'.encode('utf-8'))
msg= phone.recv(1024)print(msg)
如果你在客户端发送一个空的字符串,程序运行之后会显示发送是成功的,但是服务器没有回应,客户端也是卡在原地
之所以显示发送成功就是刚才说的原理中,发送是向我们的内存os发送,不论发送什么都会成功,但是空是无法传输的,所以服务器会一直处在等待的状态
最终导致了无法继续愉快的玩耍
现实中我们在进行与服务器交互的时候往往不会一次交流就断开,所以我们可以增加循环,进行不停的交流
#服务端
importsocket#可以将内部可能出现的参数在建立服务前进行设置,便于后期的修改
ip_port=('127.0.0.1',8080)
back_log=5buffer_size=1024tip_client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
tip_client.bind(ip_port)
tip_client.listen(back_log)
conn,addr=tip_client.accept()print('conn:',conn)print('addr',addr)#具体去看看conn和addr是个啥东西
whileTrue:
msg= conn.recv(1024)print('收到的消息是:',msg)
conn.send(msg.upper())
conn.close()
tip_client.close()#客户端
importsocket
ip_port=('127.0.0.1',8080)
buffer_size=1024tip_server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
tip_server.connect(ip_port)whileTrue:
msg= input('>>>').strip()
tip_server.send(msg.encode('utf-8'))
res=tip_server.recv(buffer_size)print('服务器返回消息',res)
tip_server.close()
但是这个在多次等待反馈运行的过程中会存在这么一个问题,客户端主动强行断开会导致服务端出现如下的错误
分析一下原因:
暂时先保留这个问题,会存在另一个问题,我们在日常中,往往是多个客户端会向同一服务器发送链接请求
我们该如何处理呢?
代码进一步改进:
主要是针对服务器的:
importsocket#可以将内部可能出现的参数在建立服务前进行设置,便于后期的修改
ip_port=('127.0.0.1',8080)
back_log=5buffer_size=1024tip_client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
tip_client.bind(ip_port)
tip_client.listen(back_log)while True: #这样,当一个用户断开后,我们就可以从backlog中拿取等待中的客户
conn,addr=tip_client.accept()print('conn:',conn)print('addr',addr)#具体去看看conn和addr是个啥东西
while True: #同时在此处增加判断机制,保证conn无效之后能及时的跳出循环,重新链接下一个客户
try:
msg= conn.recv(1024)print('收到的消息是:',msg)
conn.send(msg.upper())exceptException:break #跳出同一链接内的交互,进行洗一次的链接等待
conn.close()
tip_client.close()
此时,当多个客户端等待的时候,正在链接的客户端一旦断开链接,就可以自动的开始下一个链接反馈
马上又是周末了
这周末两个事情:
1.安装Linux的虚拟机
2.复习os模块和pickle模块
这部分内容会了之后感觉就可以购买慢慢试试我的网页了。