zoukankan      html  css  js  c++  java
  • Python进阶开发之网络编程,socket实现在线聊天机器人

    系列文章

    第一章 元类编程,已完成 ;

    第二章 网络编程,已完成 ;

    本文目录

    什么是socket?创建socket客户端创建socket服务端socket工作流程图解socket公共函数汇总实战:搭建在线聊天机器人

    . 什么是socket?

    说到网络编程,难免要提到socket

    那什么是socket呢,中文名叫"套接字",更难理解了吧。

    通俗来讲,socket表示一个网络连接,通过这个连接,使得主机间或者一台计算机上的进程间可以通讯。

    不管是不同主机,还是同一主机。既然是通信,必定有一个发送方,一个接收方。对应一个客户端,和一个服务端。

    . 创建socket客户端

    • 创建socket,建立连接
    1import socket
    2
    3# 指定IPv4协议(AF_INET),IPv6协议请使用AF_INET6
    4# 指定使用TCP协议(SOCK_STREAM),UDP协议请使用SOCK_DGRAM
    5sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    6
    7# 参数是一个tuple,tuple里指定服务器地址(域名或ip)和端口号
    8sock.connect(('www.sina.com.cn', 80))
    • 发送数据
    1# 注意这里str格式要遵循HTTP协议标准。
    2# 注意结尾一定要用
    3sock.send("GET / HTTP/1.1 Host: www.sina.com.cn ".encode("utf-8"))
    • 接收数据
     1buffer = []
    2while True:
    3 # 每次最多接收1k字节
    4 d = sock.recv(1024)
    5 if d:
    6 # Python3接收到为bytes类型,要转为str
    7 buffer.append(str(d))
    8 else:
    9 break
    10data = ''.join(buffer)

    . 创建socket服务端

    • 创建socket
    1import socket
    2
    3sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    • 绑定ip和port
    1# 注意以元组格式传入,可以是某网卡的公网ip,或0.0.0.0,或127.0.0.1
    2sock.bind(('127.0.0.1', 9999))
    • 监听端口
    1# 指定等待连接的最大数量
    2sock.listen(5)
    • 接收数据
    1while True:
    2 # 接受一个新连接,阻塞的,只有接收到新连接才会往下走
    3 sock, addr = s.accept()
    4 # 每一次连接,都要创建新线程,否则一次只能处理一个连接
    5 t = threading.Thread(target=tcplink, args=(sock, addr))
    6 t.start()
    • 连接处理函数
    1def tcplink(sock, addr):
    2 while True:
    3 data = sock.recv(1024)
    4 if data == 'exit' or not data:
    5 break
    6 sock.send('Hello, %s!' % data)
    7 sock.close()

    . socket工作流程图解

    . socket公共函数汇总

    • 发送数据
    1# 发送TCP数据,返回值:发送的字节当量
    2sk.send("data string")
    3
    4# 完整发送TCP数据,频繁调用send方法,确保数据发送完成
    5sk.sendall("data string")
    6
    7# 发送UDP数据
    8sk.sendto("data string",address)
    • 接收数据
    1# 接收TCP数据,一次最大只接收1k数据
    2sk.recv(1024)
    3
    4# 接收UDP数据,一次只接收1k数据,返回值:数据和发送方ip
    5(data,address) = sk.recvfrom(1024)
    • 获取socket信息
    1# 获取远程socket的addr,port
    2(addr, port) = sk.getpeername()
    3
    4# 获取本地socket的addr,port
    5(addr, port) = sk.getsockname()
    • 获取其他信息
     1import socket
    2
    3# 获取当前主机名
    4HostName = socket.gethostname()
    5
    6# 获取当前主机的ip
    7HOST = socket.gethostbyname(HostName)
    8
    9# 获取当前socket连接的文件描述符
    10file_no = sk.fileno()
    • 设置socket
     1# 设置连接的超时时间
    2sk.settimeout(timeout)
    3sk.gettimeout()
    4
    5# 设置为非阻塞模式,默认是0(阻塞)
    6# 非阻塞下,accept和recv时一旦无数据,则报错:socket.Error
    7sk.setblocking(1)
    8
    9# 设置socket内部参数,
    10# 具体有哪些参数,可以查看socket类的python源码
    11sk.setsockopt(level,optname,value)
    12sk.getsockopt(level,optname)

    . 实战:搭建在线聊天机器人

    通过上面的学习,我们知道,同主机下或不同主机下的两个进程要进行通信(TCP/UDP,不管是消息传输还是文件传输),必定要借助socket这个桥梁。

    那接下来,我们就一起来完成这个实战项目:在线聊天机器人

    思路:首先,客户端和服务端建立socket连接,然后客户端向服务端发送消息,服务端接收消息,并调用 图灵机器人API接口,获取回复返回给客户端。

    在这里,我们需要先去图灵机器人(http://www.tuling123.com)申请帐号,并创建机器人应用,获取授权码。

    一切准备就绪,就可以写我们的代码了。

    • 客户端
     1import socket
    2import time
    3
    4class ChatClient:
    5 def __init__(self, username, port):
    6 self.username = username
    7 self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    8 self.socket.connect(("127.0.0.1", port))
    9
    10 def send_msg(self, msg):
    11 self.socket.send("{username}::{msg}".format(username=self.username,msg=msg).encode("utf-8"))
    12
    13 def recv_msg(self):
    14 data=self.socket.recv(1024)
    15 if data:
    16 print(" 【机器人小图】"+" "+time.strftime('%Y-%m-%d:%H:%M:%S',time.localtime(time.time())))
    17 print(data.decode("utf-8"))
    18 return True
    19 return False
    20
    21 def main(self):
    22 data = self.socket.recv(1024)
    23 print(data.decode("utf-8"))
    24 msg = input("请输入消息:")
    25 self.send_msg(msg)
    26 while True:
    27 if self.recv_msg():
    28 msg=input(" 我:")
    29 self.send_msg(msg)
    30 if msg == "exit":
    31 print("聊天室已关闭")
    32 break
    33
    34if __name__ == '__main__':
    35 cc = ChatClient(username="小明", port=9999)
    36 cc.main()
    • 服务端
     1import socket
    2import time
    3import threading
    4import requests
    5import json
    6
    7
    8class ChatServer:
    9 def __init__(self, port):
    10 # 绑定服务器的ip和端口,注意以tuple的形式
    11 self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    12 self.socket.bind(("0.0.0.0", port))
    13 self.socket.listen(5)
    14 # 图灵机器人,授权码
    15 self.key = "your tuling robot key"
    16 print("正在监听 127.0.0.1 :{}...".format(port))
    17
    18 def tcplink(self, sock, addr):
    19 # 每次连接,开始聊天前,先欢迎下。
    20 sock.send("你好,欢迎来到机器人聊天器!".encode("utf-8"))
    21 while True:
    22 data = sock.recv(1024).decode("utf-8")
    23 print(sock.getpeername())
    24 print(sock.getsockname())
    25 print(sock.fileno())
    26 username = data.split("::")[0]
    27 msg = data.split("::")[1]
    28 if msg == "exit":
    29 break
    30 if msg:
    31 print("【"+username+"】 "+time.strftime('%Y-%m-%d:%H:%M:%S',time.localtime(time.time())))
    32 print(msg)
    33 response = self.get_response(msg)
    34 sock.send(response.encode("utf-8"))
    35 sock.close()
    36 print("与 {} 结束聊天!".format(username))
    37
    38 def get_response(self, info):
    39 # 调用图灵机器人API
    40 url = 'http://www.tuling123.com/openapi/api?key=' + self.key + '&info=' + info
    41 res = requests.get(url)
    42 res.encoding = 'utf-8'
    43 jd = json.loads(res.text)
    44 return jd['text']
    45
    46 def main(self):
    47 while True:
    48 sock, addr = self.socket.accept()
    49 t=threading.Thread(target=self.tcplink, args=(sock, addr))
    50 t.start()
    51
    52if __name__ == '__main__':
    53 cs = ChatServer(port=9999)
    54 cs.main()

    将服务端程序跑起来,然后运行客户端,看下效果。

    至此,我们看到我们机器人已经正常和我们调侃。


  • 相关阅读:
    java web项目打包.war格式
    version 1.4.2-04 of the jvm is not suitable for thi
    Sugarcrm Email Integration
    sharepoint 2010 masterpage中必须的Content PlaceHolder
    微信开放平台
    Plan for caching and performance in SharePoint Server 2013
    使用自定义任务审批字段创建 SharePoint 顺序工作流
    Technical diagrams for SharePoint 2013
    To get TaskID's Integer ID value from the GUID in SharePoint workflow
    how to get sharepoint lookup value
  • 原文地址:https://www.cnblogs.com/wongbingming/p/8973898.html
Copyright © 2011-2022 走看看