Stable and reliable transmission protocol, often used for accurate data transmission,
The concept of TCP
Transmission Control Protocol (TCP) is a connection-oriented, reliable, byte stream based transport layer communication Protocol.
The concept of the socket
A socket (socket for short) is a tool for communication between processes. Processes need to use this socket to communicate on the network. It is responsible for the transfer of network data between processes, like a data porter. It is no exaggeration to say that all applications or software related to the network use sockets.
The client
Here is a general process for developing a TCP application client, followed by the code:
-
Create a client socket object
-
Establish a connection to the server socket
-
To send data
-
Receive data
-
Close the client socket
from socket import *
class Cilent_Socket:
def __init__(self):
self.tcp_client_socket = socket(AF_INET, SOCK_STREAM) # AF_INET indicates ipv4 address and SOCK_STREAM indicates TCP protocol
self.tcp_client_socket.connect(('192.168.137.1'.8989)) Connect to server, specify server IP and port
def run(self):
while True:
# User input data
send_data = input("我:")
if len(send_data)==0:
print('Disconnected! ')
break
if send_data == "quit" or send_data == "exit" or send_data =='Bye'or send_data =='bye':
self.tcp_client_socket.send(send_data.encode("gbk"))
recv_data = self.tcp_client_socket.recv(4096).decode('gbk')
print('small is beautiful:, recv_data)
self.tcp_client_socket.close()
break
self.tcp_client_socket.send(send_data.encode("gbk")) Receive the maximum 4096 bytes of data sent by the other party
recv_data = self.tcp_client_socket.recv(4096).decode('gbk')
print('small is beautiful:, recv_data)
Close the socket
self.tcp_client_socket.close()
def main(a):
client = Cilent_Socket()
client.run()
if __name__ == '__main__':
main()Copy the code
The __init__ method in the code above initializes a client socket and establishes a long connection with the server, and the run() method is used to send messages to the daemon and receive messages from the daemon.
The service side
The basic steps to create a server application are:
-
Create a server-side socket object
-
Bind port number
-
Set up to monitor
-
Waiting to accept a connection request from a client
-
Receive data
-
To send data
-
Close the socket
To create a robot that can automatically reply, as long as the loop receives the information input by the user, the input keywords are judged, and the corresponding keywords can be given to the user in advance in the background, or the API interface is known to have been done. The following two cases will be described separately.
1. Customize message keyword reply
from socket import *
import time
import random
class Server_Socket:
def __init__(self):
tcp_server_socket = socket(AF_INET, SOCK_STREAM)
tcp_server_socket.setsockopt(SOL_SOCKET, SO_REUSEADDR, True) Set port reuse
tcp_server_socket.bind((' '.8989)) Bind server ports
tcp_server_socket.listen(128)
self.tcp_server_socket = tcp_server_socket
self.chat_list = ['It's a beautiful day, let's go out with our friends.'.'Did you study today?'.'I don't know what to eat.'.'Thin blue Mushroom'.'Good randy Hill'.'Let's go to the movies.'.'Go eat something good.'] # Define the initial message reply list
def start(self):
client_socket, client_addr = self.tcp_server_socket.accept()
while True:
Receive the data sent by the other party
recv_data = client_socket.recv(4096).decode('gbk') Receive 4096 bytes
if len(recv_data) == 0:
print("End of program")
break The following string is used to judge the user's input logic
elif recv_data =="quit" or recv_data =="exit" or recv_data =='Bye' or recv_data =='bye' or recv_data =='goodbye':
client_socket.send('goodbye'.encode('gbk'))
break
elif "Hello" in recv_data or "hello" in recv_data:
client_socket.send("Hello".encode('gbk'))
elif "sb" in recv_data or "SB" in recv_data or "Stupid" in recv_data or "Goods" in recv_data :
client_socket.send("You are stupid, your whole family is stupid!!".encode('gbk'))
elif "Base" in recv_data or "Stupid" in recv_data :
client_socket.send("You fool!.encode('gbk'))
elif "Eat" in recv_data or "hello" in recv_data:
client_socket.send("Braised pork in brown sauce, dongpo elbow...".encode('gbk'))
elif "Play" in recv_data or "hello" in recv_data:
client_socket.send("Yunnan Lijiang is good!".encode('gbk'))
elif "Name" in recv_data or "name" in recv_data:
client_socket.send("My name is Mei, number 9527, ha ha...".encode('gbk'))
elif "Time" in recv_data or "time" in recv_data:
client_socket.send(('Now the time is :'+time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))).encode('gbk')) Return the current time
else:
self.chat_list.append(recv_data) Collect user input information and enrich vocabulary
rand_idx = random.randint(0, len(self.chat_list) - 1) Get a message by random subscript
send_data = self.chat_list[rand_idx] # Send the information to the client
client_socket.send(send_data.encode('gbk')) If the socket is closed, the client can no longer be serviced. If the socket is closed, the client can only be reconnected
client_socket.close()
def main(a):
server = Server_Socket()
server.start()
if __name__ == '__main__':
main()Copy the code
The code above is the chatbot server code, and the user can have a general chat, return the current time, the code logic is not complex, the advantage is that can be customized.
2. Call the Turing robot API to achieve automatic reply
The interface of the Turing robot can realize functions: Chinese chat, emotion engine and so on. To use Turing’s API, you need to register on its website, create a robot, obtain an APIkey, and then use the API. Here is the url entry:
www.turingapi.com/
Here are some useful excerpts from its API documentation:
encoding
Utf-8 (all calls to the Turing API are encoded in UTF-8)
Address of the interface
Openapi.tuling123.com/openapi/api…
Request way
HTTP POST
Request parameters
The request parameters are in JSON format.
{ "reqType": 0."perception": { "inputText": { "text": "Hotel nearby." }, "inputImage": { "url": "imageUrl" }, "selfInfo": { "location": { "city": "Beijing"."province": "Beijing"."street": "Information path"}}},"userInfo": { "apiKey": ""."userId": "" }}Copy the code
Parameters that
parameter | type | Whether must | Value range | instructions |
---|---|---|---|---|
reqType | int | N | – | Input types :0- text (default), 1- picture, 2- audio |
perception | – | Y | – | The input information |
userInfo | – | Y | – | User preferences |
perception
parameter | type | Whether must | Value range | instructions |
---|---|---|---|---|
inputText | – | N | – | Text information |
inputImage | – | N | – | Image information |
inputMedia | – | N | – | Audio information |
selfInfo | – | N | – | Client properties |
Note: Input parameters must contain inputText or inputImage or inputMedia!
parameter | type | Whether must | Value range | instructions |
---|---|---|---|---|
text | String | Y | 1-128 characters | Enter text directly |
parameter | type | Whether must | Value range | instructions |
---|---|---|---|---|
url | String | Y | Picture address |
parameter | type | Whether must | Value range | instructions |
---|---|---|---|---|
url | String | Y | Audio address |
parameter | type | Whether must | Value range | instructions |
---|---|---|---|---|
location | – | N | – | Geographic location information |
parameter | type | Whether must | Value range | instructions |
---|---|---|---|---|
city | String | Y | – | city |
province | String | N | – | provinces |
street | String | N | – | The street |
userInfo
parameter | type | Whether must | Value range | instructions |
---|---|---|---|---|
apiKey | String | Y | 32 – | Robot identification |
userId | String | Y | Contains a maximum of 32 characters | Unique user identification |
groupId | String | N | The value contains a maximum of 64 characters | Group chat unique identifier |
userIdName | String | N | The value contains a maximum of 64 characters | Nickname of an intra-group user |
Output parameters
Example output:
{ "intent": { "code": 10005, "intentName": ""."actionName": ""."parameters": { "nearby_place": "Hotel"}},"results": [{"groupType": 1, "resultType": "url"."values": { "url": "http://m.elong.com/hotel/0101/nlist/#indate=2016-12-10&outdate=2016-12-11&keywords=%E4%BF%A1%E6%81%AF%E8%B7%AF"}}, {"groupType": 1, "resultType": "text"."values": { "text": "Honey, I got you the hotel info."}}}]Copy the code
Parameters that
parameter | type | Whether must | Value range | instructions |
---|---|---|---|---|
intent | – | Y | – | Request intentions |
results | – | N | – | Output result set |
intent
parameter | type | Does it include | Value range | instructions |
---|---|---|---|---|
code | int | Y | – | Output function code |
intentName | String | N | – | Name of intention |
actionName | String | N | – | Intent action name |
parameters | Map | N | – | Function related Parameters |
results
parameter | type | Does it include | Value range | instructions |
---|---|---|---|---|
resultType | String | Y | Text (text); Link (url); Audio (voice); Video (video); Images (image); Graphic (news) | The output type |
values | – | Y | – | The output value |
groupType | int | Y | – | “Group” number :0 indicates independent output. If the value is greater than 0, it may contain related content of the same group (for example, if audio and text are in a group, the content is consistent). |
Here is the code for the function that encapsulates the input keyword to return user input information for the document:
import requests
import json
def get_response(msg):
api = 'http://openapi.tuling123.com/openapi/api/v2' Interface address
data = { "perception": { "inputText": { "text": msg }, "inputImage": { "url": "imageUrl" }, "selfInfo": { "location": { "city": "Chengdu".}}}, "userInfo": {"apiKey": "", "userInfo": {"apiKey":" ", "userId": {"apiKey": "", "userId": ""}}
data = json.dumps(data) Loads a dictionary to json, loads a dictionary to python
print(data)
print('= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =')
r = requests.post(api, data=data).json() Convert the result of the POST request to JSON
print(r)
return r['results'] [0] ['values'] ['text'] # Return data
mes = get_response('the weather') # Input keywordsCopy the code
The above uses python’s built-in Request and JSON library. I have called it for several times and found that sometimes the returned results are not satisfactory. I wonder if there is a reason for not buying its package. The last version of the robot server only implemented a single user, the following implementation can be multi-user chat version:
import socket
import threading
import requests
import json
Create a web server class
class HttpWebServer:
""" Initialize the socket object """
def __init__(self, port):
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
tcp_server_socket.bind((' ', port))
tcp_server_socket.listen(128)
self.tcp_server_socket = tcp_server_socket
@staticmethod
def get_response(msg):
# Call the Turing robot API
api = 'http://openapi.tuling123.com/openapi/api/v2'
data = { "perception": { "inputText": { "text": msg }, "inputImage": { "url": "imageUrl" }, "selfInfo": { "location": { "city": "Chengdu"."province": "Sichuan"."street": ""}}},"userInfo": { "apiKey": ' '.# insert key "userId": ""}}
data = json.dumps(data) Loads a dictionary to json, loads a dictionary to python
print(data)
# print('=================================================================================')
r = requests.post(api, data=data).json() Convert the result of the POST request to JSON
print(r)
return r['results'] [0] ['values'] ['text'] # Return data
@staticmethod
def client(new_socket):
""" New socket request-response """
Accept client messages
while True:
recv_data = (new_socket.recv(4096))
recv_decode = recv_data.decode('utf-8')
If the length of the request is 0, the browser will be disconnected
if len(recv_data) == 0:
print('offline')
new_socket.close()
return
print('the handsome boy: + recv_decode)
response = HttpWebServer.get_response(recv_decode)
new_socket.send(response.encode('utf-8'))
def start(self):
""" How to start the server """
while True:
# loop accepts the request and creates the corresponding socket
new_socket, ip_port = self.tcp_server_socket.accept()
# Use multithreading to achieve multiple client access, and set the main thread daemon
sub_threading = threading.Thread(target=self.client, args=(new_socket,), daemon=True)
# Child thread open
sub_threading.start()
def main(a):
""" Program entry """
web_server = HttpWebServer(8989)
web_server.start()
if __name__ == '__main__':
main()Copy the code
Threading was used to implement multi-user chat, and the main thread daemon was used to prevent the server from crashing when data was blocked on the main thread.