首页 > 其他分享 >scoket用法

scoket用法

时间:2023-03-31 17:47:41浏览次数:33  
标签:socket send 用法 client message data 连接 scoket

一.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.........)

 

标签:socket,send,用法,client,message,data,连接,scoket
From: https://www.cnblogs.com/lihongtaoya/p/17276968.html

相关文章

  • Elasticsearch.Net+Nest基本用法
    基本用法安装Nest(安装后默认会装上Elasticsearch.Net),注意:版本尽量选择跟ES版本一致的批量初始化数据到ESusingNest;try{//测试环境配置SSL证书需要的设置ServicePointManager.SecurityProtocol=SecurityProtocolType.Tls12|SecurityProtocolType.Tls11......
  • 细说Python的lambda函数用法
    在Python中有两种函数,一种是def定义的函数,另一种是lambda函数,也就是大家常说的匿名函数。今天我就和大家聊聊lambda函数,在Python编程中,大家习惯将其称为表达式。1.为什么要用lambda函数?先举一个例子:将一个列表里的每个元素都平方。先用def来定义函数,代码如下defsq(x):re......
  • 细说Python的lambda函数用法
    在Python中有两种函数,一种是def定义的函数,另一种是lambda函数,也就是大家常说的匿名函数。今天我就和大家聊聊lambda函数,在Python编程中,大家习惯将其称为表达式。1.为什么要用lambda函数?先举一个例子:将一个列表里的每个元素都平方。先用def来定义函数,代码如下 defsq(x):......
  • SQL case when then else end 组合用法~
     在数据表设计的时候,我们经常会用到bit,int等字段来表示一些值,例如下面表中我们性别列用0表示男,1表示女 IdNameGender1张三02李四1 我们直接查询时候,想把0变成男,1变成女。selectIdas编号,Nameas姓名,casethenGender=0when'男't......
  • 浅析C++11 lambda表达式用法
    Lambda表达式(匿名函数、Lambda函数)是现代C++在C++11和更高版本中的一个新的语法糖,可以让我们快速便捷的创建一个函数。[capture-list](params)mutableexceptionattribute->return-type{body}capture-list:捕获列表,一般在Lambda表达式开头,捕获上下文中的变量,用......
  • unity中Dictionary用法
    作用在unity中序列化显示,每个key只能对应一个值,对应关系线性实例化Dictionary<key,value>字典名Dic;可嵌套Dictionaty<key1,Dictionary<key2,value>Dic>Dict1;常见方......
  • (转)Golang panic用法
    原文:https://zhuanlan.zhihu.com/p/373653492Golangpanic用法Go语言追求简洁优雅,所以,Go语言不支持传统的try…catch…finally这种异常,因为Go语言的设计者们认为,将异常......
  • 5.join原理及用法
    join用法及原理Sql查询的基本原理表查询的分类单表查询根据WHERE条件过滤表中的记录,然后根据SELECT指定的列返回查询结果两表连接查询使用ON条件对两表进......
  • ThinkPHP框架:更新个别字段的值setField、setInc、setDec的用法
    ThinkPHP有三个更新个别字段的值的函数,分别为setField、setInc、setDec。setInc():将数字字段值增加setDec():将数字字段值减少setField,根据条件更新一个或多个字段的值......
  • js中closest()的用法
    JavaScript中的closest()方法用于检索最接近的祖先,或者元素的父项与选择器匹配。如果没有找到祖先,则该方法返回 null 。此方法遍历文档树中的元素及其父元素,并继续遍历......