简体   繁体   中英

Python Mutli-chat socket errors

I am writing a multi-chat which consists of the Client handler, the server and chat record. The Client should allow multiple chats. At the moment it doesn't allow for even one chat, I get an error message after the name has been entered.

This is the Client handler file

from socket import*
from codecs import decode
from chatrecord import ChatRecord
from threading import Thread
from time import ctime

class ClientHandler (Thread):

def __init__(self, client, record):
     Thread.__init__(self)
     self._client = client
     self._record = record

def run(self):
    self._client.send(str('Welcome to the chatroom!'))
    self._name = decode(self._client.recv(BUFSIZE),CODE)
    self._client.send(str(self._record),CODE)
    while True:
        message = decode(self._client.recv(BUFSIZE),CODE)
        if not message:
            print('Client disconnected')
            self._client.close()
            break
        else:
            message=self._name +'' + \
                    ctime()+'\n'+message
            self._record.add(message)
            self._client.send(str(self._record),CODE)

HOST ='localhost'
PORT = 5000
ADDRESS = (HOST,PORT)
BUFSIZE = 1024
CODE = 'ascii'
record = ChatRecord()
server = socket(AF_INET,SOCK_STREAM)
server.bind(ADDRESS)
server.listen(5)

while True:
    print ('Waiting for connection...')
    client,address = server.accept()
    print ('...connected from:',address)
    handler = ClientHandler(client,record)
    handler.start() 

This is the server file

from socket import *
from codecs import decode

HOST ='localhost'
PORT = 5000
BUFSIZE = 1024
ADDRESS = (HOST,PORT)
CODE = 'ascii'

server = socket(AF_INET,SOCK_STREAM)
server.connect(ADDRESS)
print (decode(server.recv(BUFSIZE), CODE))
name = raw_input('Enter your name:')
server.send(name)

while True:
    record = server.recv(BUFSIZE)
    if not record:
        print ('Server disconnected')
        break
    print (record)
    message = raw_input('>')
    if not message:
        print ('Server disconnected')
        break
    server.send(message, CODE)
server.close()

This is the Chartrecord

class ChatRecord(object):
def __init__(self):
    self.data=[]
def add(self,s):
    self.data.append(s)
def __str__(self):
    if len(self.data)==0:
        return 'No messages yet!'
    else:
        return'\n'.join(self.data)

This is the error message I get when running the chat record. I can enter a name then after that I get the error message below

Waiting for connection...
('...connected from:', ('127.0.0.1', 51774))
Waiting for connection...
Exception in thread Thread-1:
Traceback (most recent call last):
  File     "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/threadin g.py", line 532, in __bootstrap_inner
self.run()
  File "/Users/basetsanamanele/Documents/workspace/HAAAAAAAFF/ClientHandler", line 17, in run
self._client.send(str(self._record),CODE)
TypeError: an integer is required

Please assist

Edit: Also, your server isn't accepting/listing for connections

You should make the server multithreaded so that it can send and receive at the same time. Here's how it might look:

import socket
import os
from threading import Thread
import thread

def main():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    s.bind((host,port))
    s.listen(10)
    serverThreads = []

    while True:
        print "Server is listening for connections..."
        client, address = s.accept()
        serverThreads.append(Thread(target=runserver, args=(client,address)).start())
    s.close()

def runserver(client, address):
    clients = set()
    lockClients = threading.Lock()
    print ("Connection from: " + address)
    with lockClients:
        clients.add(client)
    try:    
        while True:
            data = client.recv(1024)
            if data:
                print data.decode()
                with lockClients:
                    for c in clients:
                        c.sendall(data)
            else:
                break
    finally:
        with lockClients:
            clients.remove(client)
            client.close()

When you send a string over TCP you need to encode it to bytes. So your client file should look like this instead:

def run(self):
    self._client.send(('Welcome to the chatroom!').encode())
    self._name = self._client.recv(BUFSIZE).decode()
    self._client.send(str(self._record),CODE)
    while True:
        message = self._client.recv(BUFSIZE).decode()
        if not message:
            print('Client disconnected')
            self._client.close()
            break
        else:
            message=self._name +'' + \
                    ctime()+'\n'+message
            self._record.add(message)
            self._client.send(self._record.encode())

I much prefer the .encode() and .decode() syntax as it makes the code a little more readable IMO.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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