为什么要有套接字编程?

在上节课的学习中,我们学习了OSI七层协议,但是如果每次进行编程时我们都需要一层一层的将各种协议使用在我们的程序中,这样编写程序实在是太麻烦了,所以为了让程序的编写更加的简单,对OSI协议进行了封装,使我们只需要调用相应的接口就可以进行信息的接收与发送,而不用关注底层协议的实现

什么是套接字编程?

套接字是在应用层与底层之间的一个虚拟层,其中有一系列的接口,通过套接字的接口进行底层协议的设置,实际上就相当于把复杂的协议进行了隔离,只是留下接口进行设置,极大的降低了编程难度

套接字编程不知在python中使用,在其它语言中也是网络编程的实现方式,只不过调用的语法不太相同

如何使用套接字编程?

要进行套接字编程实现计算机间的信息传递至少需要两台电脑,根据C/S构架,需要编写一个客户端一个服务端

服务端的编写:

我们在进行服务端的编写时,可以参考我们使用手机的过程

import socket
import time
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 相当于买一台手机
server.bind(("127.0.0.1",8088)) # 为手机绑卡
server.listen(5) # 将手机开机进入随时可以监听电话的状态

while True:
   conn,address = server.accept()  # 等待电话的接入,获取来电显示
   while True:
       try:
           res = conn.recv(1024) # 听对方说的话
           print(res.decode("utf-8"))
           if not res:
               conn.close()  # 挂断电话
               break
           # time.sleep(10)
           conn.send(res.upper())  # 随着电话说话
       except ConnectionResetError as e:
           print(e)
           conn.close()
           break
   print("开始等待下一个客户端的链接")  

客户端的编写

import socket
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)  # 创建一个socket对象
client.connect(("127.0.0.1",8088))  # 给服务器打电话
while True:
   msg = input("请输入信息:")
   if not msg:
       continue
   if msg in ["q"]:
       client.close()
       break
   try:
       client.send(msg.encode("utf-8"))
       msg = client.recv(1024)
       print(msg)
   except ConnectionResetError as e:
       print(e)
       client.close()
       break

在进行通讯时容易出现的问题

非正常退出的问题

当客户端进行非正常退出时:

当我们的客户端与服务端进行通讯时,客户端经常会非正常退出,此时服务端再对客户端发送数据或者接受客户端的请求服务端就会报错而导致服务器停止运行,这种事情时万万不能发生的,所以要尽量避免发生这种情况,我们需要在服务端使用异常处理机制进行处理,在检测到异常后主动与客户端断开连接。

当服务器非正常退出时:

当客户端与服务端进行通讯时,如果服务器非正常退出,此时再对服务器发送信息就会在客户端报错,导致客户端停止运行,此时也需要在客户端使用异常处理机制,在检测到异常后直接断开与服务器的链接

正常退出情况

当客户端正常退出时:

在客户端正常退出时会向服务器发送一条信息,此条信息会在服务器端显示为空字符串,此时我们只需要对接收的字符串进行判断就可以,当字符串为空时就断开与客户端的链接

当服务器进行正常退出时:

当服务器进行正常退出后,不会像客户端发送任何信息,我们只需要跟服务器异常退出时一样进行异常检测就可以,检测到异常后直接断开与服务器的链接即可

发送信息为空的情况

当客户端发送为空的字符串时,由于socket的优化机制,当检测到发送的消息为空时就默认不会进行发送,但是在客户端进行了发送,客户端进入recv等待的状态,服务器由于为检测到信息,所以还是在recv状态,此时就会进入死循环,所以我们需要对客户端发送的信息进行判断,如果是空时就直接进行循环,不进行发送

当服务器发送的字符串为空时,也会发生同样的情况,所以需要在服务端也进行判断。

最新文章

  1. SharePoint 2013技巧分享系列 - 隐藏Blog和Apps左侧导航菜单
  2. 【一周读书】All life is problem solving
  3. $(document).ready、body.Onload()和 $(window).load的区别
  4. C# 线程(五):线程池
  5. Codeforces Educational Codeforces Round 3 A. USB Flash Drives 水题
  6. H - A+B for Input-Output Practice (VII)
  7. Memcached应用总结
  8. 实验记录一 初步接触cortex-M3
  9. 关于jQuery的条件判断问题
  10. 《java.util.concurrent 包源码阅读》12 线程池系列之ThreadPoolExecutor 第二部分
  11. IP地址、子网掩码、网关、DNS服务器
  12. JS 实现blob与base64互转
  13. springboot缓存注解——@Cacheable和@CacheConfig
  14. UDP套接字编程 返回系统时间
  15. springboot使用Redis,监听Redis键过期的事件设置与使用代码
  16. event.target解析
  17. Python实现switch效果
  18. zabbix问题记录
  19. 【hdu】4521 小明序列【LIS变种】【间隔至少为d】
  20. 如何使用GCC生成动态库和静态库

热门文章

  1. LDA的参数确定和主题数确定方法
  2. 菜鸟刷面试题(五、Java容器篇)
  3. JavaScript相等运算符
  4. xftp传输文件失败
  5. CPU内部结构图
  6. 8.8 JQuery框架
  7. LeetCode 128. 最长连续序列(Longest Consecutive Sequence)
  8. antd源码分析之——折叠面板(collapse)
  9. debian上搭建私有docker仓库
  10. zabbix监控nginx+php-fpm,mysql+主从复制+高可用,tomcat,redis web状态