简体   繁体   English

服务器只与一个客户端连接,Python Socket

[英]Server has connection only with one client, Python Socket

First of all, I hope I'm not writing too much.首先,我希望我没有写太多。 I'm new and I want that no one has a doubt, that everything will be clear for the readers.我是新来的,我希望没有人有疑问,所有的事情都会对读者一清二楚。 I hope someone can help me.我希望有人可以帮助我。

I have been working in a socket server and client for some weeks.我已经在套接字服务器和客户端工作了几个星期。 As time passes I add more features.随着时间的推移,我添加了更多功能。 At the beginning, it was just about having an echo server .一开始,它只是为了拥有一个echo server Afterwards, I did a server that returns time, random number or other specific things the client asked.之后,我做了一个服务器,返回时间、随机数或客户端询问的其他特定内容。 And for last thing, I added to the scripts so the server can accept 2 clients so they can talk between them.最后,我添加到脚本中,以便服务器可以接受 2 个客户端,以便他们可以在它们之间进行通信。 However, the client couldn't write the messages he wanted because he needed always to wait until the second client answers.但是,客户端无法编写他想要的消息,因为他总是需要等到第二个客户端应答。 When I got stuck with this problem, I learned about Threads .当我遇到这个问题时,我了解了Threads

So the next feature I wanted to add and it's where I'm stuck for about two or three weeks is the part where two clients can send to each other messages without stop and without the need of waiting like before they would need.所以我想添加的下一个功能是我被困了大约两三个星期的部分是两个客户端可以不间断地向彼此发送消息的部分,而不需要像他们需要的那样等待。

I have a script of the server:我有一个服务器脚本:

 import socket import threading from datetime import datetime from random import randint global num num = 0 class serverThread(threading.Thread): def __init__(self): global num num = num + 1 self.id = num threading.Thread.__init__(self) client, address = server.accept() self.client = client self.address = address print "serverThread init finished-" + str(self.id) def run(self): print "r1 num-" + str(self.id) size = 1024 while True: #try: print "r2*************-" + str(self.id) data = self.client.recv(size) print "r3..... " + data print "r4-" + str(self.id) if data: print "r5-" + str(self.id) response = data self.client.send(response) print "r6-" + str(self.id) else: print "r7-" + str(self.id) raise Exception('Client disconnected-' + str(self.id) ) #except: # print "Except" # self.client.close() # return def create(ipHost, port): server = socket.socket() server.bind((ipHost, port)) print "The server was created successfully." return server def listen(server): server.listen(5) c1 = serverThread() c1.start() c2 = serverThread() c2.start() print "finished both threads created" while c1.isAlive() and c2.isAlive(): continue server = create("0.0.0.0", 1729) listen(server)

As you can see I'm not using try and except because I don't know good how to use them.正如你所看到的,我没有使用tryexcept因为我不知道如何使用它们。

My second script, the client:我的第二个脚本,客户端:

 import socket import threading class sendThread(threading.Thread): def __init__(self, ip, port): threading.Thread.__init__(self) self.client = socket.socket() self.port = port self.ip = ip self.client.connect((self.ip, self.port)) print "[+] New send thread started for "+ip+":"+str(port) + "...Everything went successful!" def run(self): while True: data = raw_input("Enter command:") self.client.send("Client sent: " + data) class receiveThread(threading.Thread): def __init__(self, ip, port): threading.Thread.__init__(self) self.client = socket.socket() self.ip = ip self.port = port self.client.connect((str(self.ip), self.port)) print "[+] New receive thread started for "+ip+":"+str(port) + "...Everything went successful!" def run(self): print "Entered run method" size = 1024 while True: data = self.client.recv(size) if data != "" or data: print "A client sent " + data def client(): port = 1729 ip = '127.0.0.1' print "Connection from : "+ip+":"+str(port) receive = receiveThread(ip, port) print "b1" receive.start() print "b2" send = sendThread(ip, port) print "b3" send.start() while send.isAlive() and receive.isAlive(): continue print "-----END of While TRUE------" print "Client disconnected..." client()

I thought it would be a good idea to describe my scripts, go step by step in my code, maybe it helps so it will be more readable.我认为描述我的脚本是一个好主意,在我的代码中一步一步地进行,也许它会有所帮助,因此它会更具可读性。

The Server script服务器脚本

I create a socket server, and call the bind method.我创建了一个套接字服务器,并调用了bind方法。 I call for the listen method and begin to receive the clients.我调用了listen方法并开始接收客户端。 I create a thread for each client that I will accept ( accept() ) and receive ( recv ) data from.我为每个客户端创建一个线程,我将接受( accept() )并从中接收( recv )数据。 After I create each client thread I print a message that they were created successfully.创建每个客户端线程后,我会打印一条消息,说明它们已成功创建。 When I start the clients threads they wait for receiving a message sent ( recv ) and send it.当我启动客户端线程时,他们等待接收发送的消息( recv )并发送它。 If I'm not wrong, I just need the send method and not to tell to who send it.如果我没有错,我只需要send方法而不是告诉发送它。

The Client script客户端脚本

The client will have two threads.客户端将有两个线程。 One for sending messages (as much as you want) and one for always waiting for messages that another client sent.一个用于发送消息(尽可能多),另一个用于始终等待另一个客户端发送的消息。

The problem问题

When I want to run the server before running the two clients it prints当我想在运行它打印的两个客户端之前运行服务器时

The server was created successfully.

I run 2 clients and both print:我运行 2 个客户端并且都打印:

Connection from : 127.0.0.1:1720
[+] New receive thread started for 127.0.0.1:1720...Everything went successful!
b1
Entered run method
b2
[+] New send thread started for 127.0.0.1:1720...Everything went successful!
b3
Enter command:

However, there is a problem in the connection between the second client created and the server.但是,创建的第二个客户端和服务器之间的连接存在问题 I did that when the server receives a message sent by a client, it will print the message as output in the server.我这样做了,当服务器收到客户端发送的消息时,它会将消息打印为服务器中的输出。 However, when the first client sends a message it prints it.但是,当第一个客户端发送消息时,它会打印它。 But not when the second client sends.但不是当第二个客户端发送时。

I even tried to copy the client script and put it in a new file, so the two clients are from two different files and maybe find a problem.我什至试图复制客户端脚本并将其放入一个新文件中,因此两个客户端来自两个不同的文件,可能会发现问题。 However, it didn't help.然而,它没有帮助。 I tried to run the first file and then the second file, and vice versa.我尝试运行第一个文件,然后运行第二个文件,反之亦然。 Always the second client had a problem with the server.总是第二个客户端的服务器有问题。 (By the way, I would also want to know why the client file doesn't print the message he himself sends (he will still receive it from the server) but that's a secondary problem). (顺便说一句,我还想知道为什么客户端文件不打印他自己发送的消息(他仍然会从服务器接收消息),但这是次要问题)。

I hope I didn't do it too long or too far, hope someone can help find the problem in my code.我希望我没有做太长或太远,希望有人可以帮助找到我代码中的问题。

I would be even happier if you tell what is the problem in the code, instead of giving me one that you created or find!如果你能说出代码中的问题,而不是给我你创建或找到的问题,我会更高兴!

I think it could be because you have 2 threads trying to accept a connection at the same time?我认为这可能是因为您有 2 个线程试图同时接受一个连接?

You create the first thread, then that thread's init function accepts a connection with socket.accept().您创建第一个线程,然后该线程的 init 函数接受与 socket.accept() 的连接。 Then, before you receive a connection, you instantly create another server thread, which ALSO calls accept() on the socket.然后,在您收到连接之前,您立即创建另一个服务器线程,该线程也在套接字上调用 accept()。 My guess is that this 2nd accept call isn't registered, as 1 thread is already 'locking' that object.我的猜测是第二个接受调用未注册,因为 1 个线程已经“锁定”了该对象。

Instead of creating 2 thread immediately, maybe try only creating a thread once someone connects to the socket?与其立即创建 2 个线程,不如尝试在有人连接到套接字后才创建一个线程?

client = socket.accept()
serverThread1 = serverThread(client)
serverThread2.start()
client = socket.accept()
serverThread2 = serverThread(client)
serverThread2.start()

Where the serverThread class now takes the client socket as a constructor parameter. serverThread 类现在将客户端套接字作为构造函数参数。

You access to the server with two clients in the same time.您可以同时使用两个客户端访问服务器。 So to solve this problem, just add a delay time.所以要解决这个问题,只需增加一个延迟时间。

time.sleep(1)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM