0

I am trying to code a simple chat programm , but a problem that seems to be unsolvable appeared.(I can't even find the origin)

Lets say we have got 2 chatrooms and the are called "chatA" and "chatB" and there is one user in each chatroom ("BOB" is in "chatA" and "PETE" is in "chatB") and they are writing , even though the are the only ones that are using their chatroom. Why do the receive every message the other people write, even though they are in different chatrooms ?

Server code:

import socket
from thread import start_new_thread

clientNameList = []
clientList = []
roomNameList = []
roomList = []

class Client(object):
    def __init__(self, username, room="none"):
        self.username = username
        self.room = room

class Room(object):
    def __init__(self, name, maxNumber, adminUser, userList=[], messageList=[]):
        self.name = name
        self.maxNumber = maxNumber
        self.adminUser = adminUser
        self.userList = userList
        self.messageList = messageList

def main():
    host = ''
    port = 12

    s = socket.socket()

    s.bind((host, port))

    s.listen(5)

    while True:
        c, (clientIp, clientPort) = s.accept()
        start_new_thread(newClient, (c,))
    s.close()
def newClient(c):
    username = c.recv(32)
    if username not in clientNameList:
        clientNameList.append(username)
        clientList.append(Client(username))
        c.send("SUCCE welcome, '%s'" %str(username))
        print username," connected!"
        start_new_thread(clientRecv, (c, username,))
        start_new_thread(clientSend, (c, username,))
    else:
        c.send("ERROR username already taken")
def clientRecv(c, username):
    running = True
    while running:
        try:
            message = c.recv(1024)
        except:
            clientIndex = clientNameList.index(username)
            activeRoom = clientList[clientIndex].room
            activeRoomIndex = roomNameList.index(activeRoom)
            roomList[activeRoomIndex].userList.remove(username)
            roomList[activeRoomIndex].messageList.append("%s left" %str(username))
            del clientList[clientIndex]
            clientNameList.remove(username)
            running = False
        if message[:5] == "/help":
            c.send("/help = this;\n/join 'room' = join room;\n/quit = quit\n/create 'roomname','max. num of Clients' = create room\n/users = display users(if not in a room, display all)\n/rooms = display chatrooms")
        elif message[:5] == "/join":
            if message[6:] not in roomNameList:
                c.send("ERROR room doesn't exist")
            else:
                clientIndex = clientNameList.index(username)
                newRoom = message[6:]
                newRoomIndex = roomNameList.index(newRoom)
                if roomList[newRoomIndex].maxNumber == len(roomList[newRoomIndex].userList):
                    activeRoom = clientList[clientIndex].room
                    c.send("ERROR '%s' is full" %str(activeRoom))
                else:
                    if clientList[clientIndex].room != "none":
                        clientIndex = clientNameList.index(username)
                        activeRoom = clientList[clientIndex].room
                        activeRoomIndex = roomNameList.index(activeRoom)
                        activeRoomUserIndex = roomList[activeRoomIndex].userList.index(username)
                        del roomList[activeRoomIndex].userList[activeRoomUserIndex]
                        roomList[activeRoomIndex].messageList.append("%s left the chatroom" %str(username))
                        c.send("SUCCE you left '%s'" %str(activeRoom))
                    roomList[newRoomIndex].userList.append(username)
                    roomList[newRoomIndex].messageList.append("%s joined" %str(username))
                    c.send("SUCCE you joined '%s'" %str(newRoom))
                    clientList[clientIndex].room = newRoom
        elif message[:5] == "/quit":
            c.send("SUCCE bye")
            clientIndex = clientNameList.index(username)
            activeRoom = clientList[clientIndex].room
            if activeRoom != "none":
                activeRoomIndex = roomNameList.index(activeRoom)
                roomList[activeRoomIndex].userList.remove(username)
                roomList[activeRoomIndex].messageList.append("%s left" %str(username))
            del clientList[clientIndex]
            clientNameList.remove(username)
            running = False
        elif message[:7] == "/create":
            arguments = message[8:].split(",")
            if len(arguments) != 2:
                c.send("ERROR syntax")
            else:
                if arguments[0] in roomNameList:
                    c.send("ERROR room already exist")
                else:
                    roomNameList.append(arguments[0])
                    try:
                        roomList.append(Room(arguments[0], int(arguments[1]), username))
                        c.send("SUCCE room '%s' created" %str(arguments[0]))
                    except:
                        c.send("ERROR syntax")
        elif message[:6] == "/users":
            if clientList[clientNameList.index(username)].room == "none":
                print "%s used /users on ALL" %str(username)
                for user in clientNameList:
                    c.send(user)
            else:
                print "%s used /users on %s" %(str(username), str(clientList[clientNameList.index(username)].room))
                for user in roomList[roomNameList.index(clientList[clientNameList.index(username)].room)].userList:
                    c.send(user)
        elif message[:6] == "/rooms":
            for room in roomNameList:
                c.send(room)
        elif message[:4] == "/mod":
            if len(message) < 6:
                c.send("ERROR not enough arguments")
            else:
                if clientList[clientNameList.index(username)].room != "none":
                    if roomList[roomNameList.index(clientList[clientNameList.index(username)].room)].adminUser != username:
                        c.send("ERROR you are not the room-admin")
                    else:
                        try:
                            newValue = int(message[5:])
                            roomList[roomNameList.index(clientList[clientNameList.index(username)].room)].maxNumber = newValue
                            c.send("SUCCE updated")
                        except:
                            c.send("ERROR invalid value")
                else:
                    c.send("ERROR you have to be inside a room to modify it")
        elif message[:6] == "/print":
            for message in roomList[int(message[7:])].messageList:
                print message
        else:
            if clientList[clientNameList.index(username)].room == "none":
                c.send("ERROR you are not in a chatroom")
            else:
                roomList[roomNameList.index(clientList[clientNameList.index(username)].room)].messageList.append("%s: %s" %(username, message))
def clientSend(c, username):
    last = 0
    running = True
    while running:
        try:
            clientIndex = clientNameList.index(username)
            if clientList[clientIndex].room != "none":
                activeRoom = clientList[clientIndex].room
                activeRoomIndex = roomNameList.index(activeRoom)
                messageCount = len(roomList[activeRoomIndex].messageList)-1
                if messageCount != last:
                    if messageCount - last > 1:
                        c.send("SUCCE %s %s\n" %(str(activeRoom),str(roomList[activeRoomIndex].messageList[last+1])))
                        last +=1
                    else:
                        c.send("SUCCE %s %s" %(str(activeRoom),str(roomList[activeRoomIndex].messageList[last+1])))
                        last +=1
        except:
            running = False
main()

Client code:

import socket
from thread import start_new_thread
import time
import os

def main():
    host = raw_input("IP ->")
    port = 12

    s = socket.socket()
    s.connect((host, port))


    userinput = raw_input("username ->")
    s.send(userinput)
    print s.recv(128)

    time.sleep(1)
    os.system("cls")

    start_new_thread(sender, (s,))
    receiver(s)

def receiver(s):
    running = True
    while running:
        servermessage = s.recv(256)
        print "[>>]",servermessage
        if servermessage == "SUCCE bye":
            running = False

def sender(s):
    running = True
    while running:
        userinput = raw_input()
        if userinput == "/quit":
            running = False
        s.send(userinput)
main()

(I added a command(/print x) for debugging purposes and it proves, that every message is being appended to every messageList of every object inside the roomList)

Why does that happen and how could i improve my code ? Thank you :)

Hans Wuast
  • 55
  • 6
  • Briefly: in `def func(lst=[]):`, the `lst` is created when the function is defined, and it is shared between all calls of that function. Immutable default arguments do that too, but it isn't an issue because you change them by throwing them away and creating new ones rather than mutating them. – TigerhawkT3 Jan 07 '17 at 08:42
  • feeling super dumb now... thanks – Hans Wuast Jan 07 '17 at 08:54
  • As the duplicate question's title implies, this behavior is often astonishing. Don't worry about it. – TigerhawkT3 Jan 07 '17 at 08:57

0 Answers0