day30

socket

#socket是一套编程接口,内部封装了一堆底层协议,隐藏了内部复杂的实现细节,提供了简单的使用接口
#按照socket编程接口来编写出的代码,就已经遵循了各种协议
'''
secket分为两种类型:
  AF_UNIX(基于文件):进程间通讯
  AF_INET(基于网络):网络通讯
'''        

服务端

import socket


# 获取tcp套接字
tcpServer = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 获取udp套接字
udpSock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

# band把地址绑定到套接字,127.0.0.1表示回还地址,1688表示端口号
tcpServer.bind(('127.0.0.1', 1688))

# 开始监听1688端口
tcpServer.listen()

# 被动接收TCP客户端链接,阻塞式,等待链接的到来
# 接收链接请求,第一个参数表示客户端的socket,第二个参数表示客户端的地址信息
while True:
   client, address = tcpServer.accept()
   print('执行')
   while True:
       # 收发数据
       try:
           data = client.recv(1024)
           print(data)
           #在linux中,如果客户端强制下线,不会抛异常,会收到空消息
           #在windows中正常关闭,会输消息
           if not data:
               #此判断用于客户端下线的问题
               client.close()
               break
           client.send('copy!'.encode('utf-8'))
       except ConnectionResetError as e:
           print(e)
           client.close()
           break
# 关闭服务
# tcpServer.close()

客户端

import socket

client = socket.socket()
# connect本质上是在进行三次握手,也是一个数据传输的过程,如果服务器没有立马响应,也会阻塞
client.connect(('127.0.0.1', 1688))

while True:
# 发送数据本质上是把数据交给操作系统来进行发送一旦数据交给了操作系统 后续的发送
# 应用程序就无法控制了,send一般不会卡,当然如果数据量很大就会阻塞
   msg = input('输入内容:')
   if msg == 'q':
       break
   if not msg:
       '''tcp内部有优化机制,当消息为空时,就不会发消息了,不会经过网络发消息,这样就会陷入死循环
          这个判断用于防止空消息
      '''
       continue
   client.send(msg.encode('utf-8'))
   # 接收数据
   data = client.recv(1024)
   print(data.decode('utf-8'))

   # 客户端执行close 是正常关闭链接会给服务器送空字节用于表示要断开链接
client.close()
原文地址:https://www.cnblogs.com/zhuqihui/p/10940361.html