1

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

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.

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. I call for the listen method and begin to receive the clients. I create a thread for each client that I will accept (accept()) and receive (recv) data from. 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. If I'm not wrong, I just need the send method and not to tell to who send it.

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:

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!

2 Answers 2

1

I think it could be because you have 2 threads trying to accept a connection at the same time?

You create the first thread, then that thread's init function accepts a connection with socket.accept(). Then, before you receive a connection, you instantly create another server thread, which ALSO calls accept() on the socket. My guess is that this 2nd accept call isn't registered, as 1 thread is already 'locking' that object.

Instead of creating 2 thread immediately, maybe try only creating a thread once someone connects to the socket?

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.

Sign up to request clarification or add additional context in comments.

3 Comments

It's a good point. However, I changed it for what you said and still the server doesn't print the message sent by the second client.
Are you sure that both clients have connected correctly?
Both clients' output print what I showed in my question below the title The problem where I wrote I run 2 clients and both print. Maybe that helps you to understand the problem? I know that both succeeded with socket.connect((ip, port)), there wasn't an error or something. More than that I don't know how to check connections.
0

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.