尝试连接时“尝试在不是套接字的东西上进行操作”

Posted

技术标签:

【中文标题】尝试连接时“尝试在不是套接字的东西上进行操作”【英文标题】:"An operation was attempted on something that is not a socket" when attempting to connect 【发布时间】:2021-11-04 15:05:30 【问题描述】:

在完成关于如何在 python 中创建一个简单的基于终端的聊天室的教程后,我想添加更多功能,最值得注意的是一个简单的 GUI。进展顺利,但我遇到了障碍。 “连接”按钮应该存储 ip 和端口的输入文本字段并将它们定义为变量,然后它们将用于连接到服务器。您可以在“def connect():”中看到这一切。单击“连接”按钮时,出现以下错误:

"Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\censored\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1892, in __call__
    return self.func(*args)
  File "c:\Users\censored\Desktop\Chatroom\client.py", line 32, in connect
    client.connect((ip, int(port)))
OSError: [WinError 10038] An operation was attempted on something that is not a socket"

另外,忽略“接收”按钮,我想我会摆脱它。

客户端脚本:

import socket
import threading
import tkinter as tk



root= tk.Tk()

canvas1 = tk.Canvas(root, width = 600, height = 600)
canvas1.pack()

entry1 = tk.Entry (root) 
canvas1.create_window(200, 140, window=entry1)

entry2 = tk.Entry (root) 
canvas1.create_window(200, 240, window=entry2)

entry3 = tk.Entry (root) 
canvas1.create_window(200, 340, window=entry3)

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

def connect():
        
        ip = entry1.get()

        port = entry2.get()

        

        
        client.connect((ip, int(port)))

button1 = tk.Button(text='connect', command=connect)
canvas1.create_window(200, 180, window=button1)

nickname = entry3.get()

print(nickname)

def receive():
    while True:
        try:
            
            message = client.recv(1024).decode('ascii')
            if message == 'NICK' :
                client.send(nickname.encode('ascii'))
            else:
                print(message)
        except:
            print("ERROR!")
            client.close()
            break


button2 = tk.Button(text='receive', command=receive)
canvas1.create_window(200, 400, window=button2)

def write():
    while True:
        message = f'nickname: input("")'
        client.send(message.encode('ascii'))

receive_thread = threading.Thread(target=receive)
receive_thread.start()

write_thread = threading.Thread(target = write)
write_thread.start()

root.mainloop()

  

这也是我的服务器脚本,它工作正常:

import threading
import socket

ip = input("Input server ip: ")
portid = input("Input server port: ")

host = ip
port = int(portid)

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((host, port))
server.listen()

clients = []
nicknames = []

def broadcast(message):
    for client in clients:
        client.send(message)

def handle(client):
    while True:
        try:
            message = client.recv(1024)
            broadcast(message)
        except:
            index = clients.index(client)
            clients.remove(client)
            client.close()
            nickname = nicknames[index]
            broadcast(f'nickname has left'.encode('ascii'))
            nicknames.remove(nickname)
            break

def receive():
    while True:
        client, address = server.accept()
        print(f"Connected with str(address)")

        client.send('NICK'.encode("ascii"))
        nickname = client.recv(1024).decode('ascii')
        nicknames.append(nickname)
        clients.append(client)

        print(f'Nickname of the newly connected client is nickname :)')
        broadcast(f'nickname joined the chat'.encode('ascii'))
        client.send('Connected!'.encode('ascii'))

        thread = threading.Thread(target = handle, args=(client,))
        thread.start()

print("server listening..")
receive()

【问题讨论】:

【参考方案1】:

客户端立即执行receive_thread.start();因为它没有连接,receive()client.close() 出错;使用关闭的client 套接字不再可能connect

您可能不应该在建立连接之前启动接收线程。

【讨论】:

以上是关于尝试连接时“尝试在不是套接字的东西上进行操作”的主要内容,如果未能解决你的问题,请参考以下文章

尝试连接到已经处理请求的套接字的传入连接会发生啥?

在连接时加入套接字 io 房间

android 套接字连接超时

“java.net.BindException:地址已在使用中”尝试为负载测试进行快速套接字创建和销毁时

具有多个连接的 C++ 服务器套接字

如何配置套接字连接超时