一.scoket基本介紹 1.scoket簡介(以下是來自chatgpt回答) 1)Socket(套接字)是電腦網路中用於描述主機之間通信的一種機制。它定義了一種標準的介面, 使得應用程式可以利用網路傳輸層提供的服務(如TCP或UDP)進行通信。 2)Socket的作用是在網路應用程式之間提供數據 ...
一.scoket基本介紹
1.scoket簡介(以下是來自chatgpt回答)
1)Socket(套接字)是電腦網路中用於描述主機之間通信的一種機制。它定義了一種標準的介面,
使得應用程式可以利用網路傳輸層提供的服務(如TCP或UDP)進行通信。
2)Socket的作用是在網路應用程式之間提供數據傳輸服務。通過Socket,應用程式可以將數據發送
到網路上的另一個應用程式,並從網路上的另一個應用程式接收數據。
3)Socket還提供了一種機制,使得應用程式可以接收來自網路上的請求,並對這些請求進行響應。
常見的網路應用程式,如Web伺服器、郵件伺服器、FTP伺服器等都使用Socket技術。此外,許多P2P
(點對點)應用程式,如BitTorrent、eMule等也使用Socket技術。Socket還可以用於實現各種網路應用
程式,如網路游戲、聊天程式等。
2.建立TCP/IP連接
1)創建一個scoket對象
socket_stream = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
第一個參數表示通信協議類型
AF_INET:適用於網路通信
AF_UNIX:適用於本地進程間通信
第二個參數表示創建什麼連接
SOCK_STREAM:表示tcp/ip連線
SOCK_DGRAM:表示udp連接
2)與服務端建立連接
# 建立連接 ip_port = ("ip", "port") # 連接的服務端ip和埠 socket_stream.connect(ip_port) # 建立連接,出錯不返回錯誤碼 socket_stream.connect_ex(ip_port) # 出錯時返回錯誤碼,不拋異常
connect()和connect_ex()選一個即可
3)發送數據
# 發送數據 data = 'hello' socket_stream.send(data.encode("utf-8")) # 發送TCP數據,當send在待發送數據量大於己端緩存區剩餘空間時,數據丟失,不會發完 # or socket_stream.sendall(data.encode("utf-8")) # 發送完整的TCP數據(迴圈調用send,sendall在待發送數據量大於己端緩存區剩餘空間時,數據不丟失,迴圈調用send直到發完)
當發送的數據較大時建議使用sendall發送
4)接收TCP數據
# 接收TCP數據。1024(變數)表示每次最多接受1M位元組的數據,recv()函數是一個阻塞函數,沒有要接收的數據時,會一直等待,直到接收到數據或出現錯誤才會返回 response_data = socket_stream.recv(1024)
5)關閉連接
# 關閉連接 socket_stream.close()
3.建立UDP連接
1)創建scoket對象
client_dgram = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
2)發送數據
# 發送數據 ip_port = ('127.0.0.1', 8080) data = 'Hello' client_dgram.sendto(data.encode("utf-8"), ip_port)
這裡發送用的是sendto()方法
3)接收數據
# 接收UDP數據數據 data = client_dgram.recvfrom(4096)
4)關閉連接
# 關閉連接 client_dgram.close()
二.使用scoket編寫聊天程式
以下部分代碼參考:https://www.yuque.com/imhelloworld/nov9az/bffcea259d3c96fb17a130acebc12801
聊天程式的話涉及兩個端,既server和click。這裡直接貼代碼了,相關註釋都是代碼里
1)server
import socket import threading # 伺服器IP地址和埠號 SERVER_IP = 'IP地址' SERVER_PORT = 埠號 # 創建一個socket對象 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 綁定IP地址和埠號 server_socket.bind((SERVER_IP, SERVER_PORT)) # 設置最大連接數,超過10後拒絕。0的話表示不接受連接,直接拒絕 server_socket.listen(10) # 客戶端列表 clients = [] def handle_client(client_socket): while True: try: # 接收客戶端發送的消息 message = client_socket.recv(10240).decode('utf-8') print("列印", message) if message == 'quert': client_socket.send(message.encode('utf-8')) else: # 廣播消息給所有客戶端 for c in clients: if c != client_socket: c.send(message.encode('utf-8')) except: # 發生異常時關閉連接 client_socket.close() clients.remove(client_socket) print("發送異常了") break # 迴圈監聽客戶端連接 while True: print('Waiting for client connections...') # 接受客戶端連接請求,新的客戶端請求時創建一個新的socket,用於處理客戶端的請求,原有的socket繼續監聽其他客戶端的連接請求; # 函數是一個阻塞函數,當沒有客戶端連接請求時,會一直等待,直到有客戶端連接請求到達 client_socket, client_address = server_socket.accept() print('客戶socket', client_socket, 'ip和埠', client_address) clients.append(client_socket) # 創建一個新的線程處理客戶端連接 client_thread = threading.Thread(target=handle_client, args=(client_socket, )) client_thread.start()
2)click
import socket import threading import time # 伺服器IP地址和埠號 SERVER_IP = 'IP地址' SERVER_PORT = 埠號 # 創建一個socket對象 client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 連接伺服器 client_socket.connect((SERVER_IP, SERVER_PORT)) def receive(): while True: try: # 接收伺服器發送的消息 message = client_socket.recv(1024).decode('utf-8') if message == 'quert': client_socket.close() break print('\n對方回答:', message) except: # 發生異常時關閉連接 client_socket.close() break def send(): while True: # 獲取用戶輸入的消息 message = input() if message == 'quert': client_socket.close() print('連接斷開,通信結束') break else: # 發送消息給伺服器 client_socket.send(message.encode('utf-8')) # 創建兩個線程,分別用於接收和發送消息 receive_thread = threading.Thread(target=receive) send_thread = threading.Thread(target=send) # 啟動線程 receive_thread.start() send_thread.start()
這裡需要註意的是,既然是聊天程式,那麼肯定涉及兩個click,兩個click代碼一致即可,運行時先運行server,後運行click,之後就可以在Terminal下建立對話了。
以上是click在同一臺電腦上,若不在同一臺電腦的,建立對話需在同一個區域網下,ip地址在dos視窗下輸入ipconfig\all即可查看,埠號可隨便填個,只要不被占用就行。
三.scoket+chatgpt建立搜索對話框
1)獲取chatgpt搜索介面,這裡就直接貼代碼了
def api(params, tokened="token"): url = "https://api.aigcfun.com/api/v1/text?key=" + tokened data = {"messages": [{"role": "system", "content": "請以markdown的形式返回答案"}, {"role": "user", "content": params}], "tokensLength": 32, "model": "gpt-3.5-turbo"} response_data = requests.post(url=url, json=data) return response_data.json()["choices"][0]["text"]
params為用戶問的問題,return返回的是chatgpt回答的答案
2)獲取到chatgpt的回答內容後返回給服務端
def receive(): while True: try: # 接收伺服器發送的消息 message = client_socket.recv(1024).decode('utf-8') data_message = api(message) while data_message == None: # 由於chatgpt有時響應的比較慢,這裡需添加個迴圈判斷 continue # if data_message == '您今日使用次數已達上限,請明日再試!': # data_message = api(params=message, tokened=token()) client_socket.send(data_message.encode('utf-8')) # 發送chatgpt回答的問題給服務端 except: # 發生異常時關閉連接 client_socket.close() break
3)目前chatpgt雖是免費的,但每天都有次數限制,所以可以請求獲取token的介面來獲取新的token。這裡就不做演示了(hhhhhh.........)