Lucas Kauffman
Lucas Kauffman

Reputation: 6891

Passing from one socket to another

I am trying to write a program that works as an intermedium. (M)

I can only use telnet to connect :

A needs to connect to M, B connects to M.

A sends data to M on a socket, M needs to pass it to B

B sends data to M on another socket

I tried this by starting four threads with a shared list

The problem is it seems it is not writing to the other socket, or even accepting writing.

Does anyone know a better way to implement this and pass it through to another socket

My code :

import sys
import arduinoReadThread
import arduinoWriteThread
import socket
class ControllerClass(object):
    '''
    classdocs
    '''
    bolt = 0
    socketArray=list()

    def __init__(self):
        self.readAndParseArgv()
        self.createThreads()

    def readAndParseArgv(self):
        array = sys.argv
        print sys.argv
        if len(array) != 3:
            print "Too few arguments : ./script host:port host:port"
        else:
            for line in array:
                if ":" in line:
                    splitted = line.split(':')
                    HOST = splitted[0]
                    print HOST
                    PORT = int(splitted[1])
                    print PORT
                    s=socket.socket(socket.AF_INET, socket.SOCK_STREAM ) #create an INET, STREAMing socket
                    s.bind((HOST,PORT)) #bind to that port
                    print "test"
                    s.listen(1) #listen for user input and accept 1 connection at a time.
                    self.socketArray.append(s)

    def createThreads(self):
        print "Creating Threads"
        sharedArray1 = list()
        sharedArray2 = list()
        s1 = self.socketArray.pop()
        s2 = self.socketArray.pop()
        sT1 = arduinoWriteThread.writeThread().run(self.bolt,sharedArray1,s2)
        sT2 = arduinoReadThread.readThread().run(self.bolt,sharedArray1,s1)
        sT3 = arduinoReadThread.readThread().run(self.bolt,sharedArray2,s2)
        sT4 = arduinoWriteThread.writeThread().run(self.bolt,sharedArray2,s1)
        sT1.start()
        sT2.start()
        sT3.start()
        sT4.start()
x = ControllerClass()
x

Two Threads : Write Thread :

import threading class writeThread ( threading.Thread ):

    def run ( self,bolt,writeList,sockeToWriteTo ):
        s = sockeToWriteTo
        while(bolt == 0):
            conn, addr = s.accept()
            if len(writeList) > 0:

                socket.send(writeList.pop(0))

Read Thread

import threading
    class readThread ( threading.Thread ):

    def run ( self,bolt,writeList,socketToReadFrom ):
        s = socketToReadFrom
        while(bolt == 0):
            conn, addr = s.accept()

            f = conn.rcv()
            print f
            writeList.append(f)

Upvotes: 2

Views: 1033

Answers (1)

Some programmer dude
Some programmer dude

Reputation: 409432

You don't really need threads for this...

When a new connection is accepted, add it to a list. When receiving anything from one of the connection in the list, send to all connections except the one you got the message from.

Use select to see which connections have send data to you.

Edit

Example using select:

# serversocket: One server socket listening on some port, has to be non-blocking
# all_sockets : List containing all connected client sockets
while True:
    readset = [serversocket]
    readset += all_sockets

    # Wait for sockets to be ready, with a 0.1 second timeout
    read_ready = select.select(readset, None, None, 0.1)

    # If the listening socket can be read, it means it has a new connection
    if serversocket in read_ready:
        new_connection = serversocket.accept()
        new_connection.setblocking(0);  # Make socket non-blocking
        all_sockets += [new_connection]
        read_ready.remove(serversocket) # To not loop over it below

    for socket in read_ready:
        # Read data from socket
        data = socket.recv(2048)
        for s in all_sockets:
            # Do not send to self
            if s != socket:
                s.send(data)

Disclaimer I have never really used the Python socket functions, the code above was made from reading the manual pages just now. The code is probably not optimal or very Pythonic either.

Upvotes: 4

Related Questions