0

MailServer.py

import socket
import sys
import os 
import threading

def respond (cmdList, user): #handling server response to the client
    global userList
    global passwordList
    
    cmd = cmdList[0] #extract relative command
    if cmd == "#EXIT":
        response = "250 Exit ok"
    if cmd == "#USERNAME":
        if (cmdList[1] + "\n") in userList:
            response = "250 Username ok"
        else:
            response = "200 Username does not exist"
            print (userList)
        
    
    return response

def thd_func(client):
    connectionSocket, addr = client
    command = connectionSocket.recv(1024)
    cmdList = command.decode().split(" ", 1)
         
    response = respond(cmdList, "")
    connectionSocket.send(response.encode())
    connectionSocket.close()

def main(argv):

    #initialize
    global userList
    global passwordList
    userList = []
    passwordList = []
    
    #create and bind the socket
    serverPort = int (argv[1])
    serverSocket = socket.socket()
    serverSocket.bind(("", serverPort))
    
    #fetch client information
    file = open ("ClientInfo.txt", "r")
    temp = file.readlines()
    file.close()
    for i in range (len(temp)):
        line = temp[i]
        if i % 2 == 0:
            userList.append(line)
        else:
            passwordList.append(line)
    
    #listen for incoming request
    serverSocket.listen(5)
    
    while True:
        client = serverSocket.accept()
        newthd = threading.Thread (target = thd_func, args = (client,))
        newthd.start()
    
    #close the socket
    serverSocket.close()

if __name__ == '__main__':
    
    #validation
    if len(sys.argv) != 2:
        print("Error: illegal parameter input") #port
        sys.exit(1)
        
    main(sys.argv)

MailClient.py

import socket
import sys

def main(argv):   
    #create and connect the socket
    clientSocket = socket.socket()
    serverName = argv[1]
    serverPort = int (argv[2])
    clientSocket.connect((serverName, serverPort))
    
    while True:
        command = input ("Client : ")
        clientSocket.send(command.encode())
        response = clientSocket.recv(1024)
        print("Server : " + response.decode())
        if response.decode() == "250 Exit ok":
            break
        
    #close the socket
    clientSocket.close()

if __name__ == '__main__':
    if len(sys.argv) != 3:
        print("Error: illegal parameter input") #address port
        sys.exit(1)
    main(sys.argv)

I am a beginner in Socket programming. I am working on a project which needs to make a simple mail server that can allow users to log in and do some simple task by inputting simple commands. So in order to do that, the server needs to handle input commands from the same client many times and respond accordingly. In MailServer.py, I am trying to use multi-threading approach to do so. However, it still doesn't work and the cmd still responds "ConnectionAbortedError: [WinError 10053] An established connection was aborted by the software in your host machine". Is there something I am missing? How can I fix it? Thank you.

  • 1
    Your server is closing the socket after responding. That means you can’t use that socket anymore on the client side for sending further requests. Additionally, your current code does not handle abnormal termination of the socket (cases where you did not intend to close the socket, but some bad network event happened). – shauli Feb 15 '21 at 06:41

1 Answers1

0
def thd_func(client):
    while True:
        connectionSocket, addr = client
        command = connectionSocket.recv(1024)
        cmdList = command.decode().split(" ", 1)
             
        response = respond(cmdList, "")
        connectionSocket.send(response.encode())
        if response == "250 Exit ok":
            connectionSocket.close()

So I modified the respond function in MailServer.py and fixed the error. If you still see any error, please feel free to add more comments or answers to this question. Thank you.

  • 1
    Unfortunately, the way you are using stream sockets is not reliable. Your code is making the assumption that when you send `k` bytes in one `send()` call the peer will receive exactly `k` bytes in one `recv()` call. This behavior is something beginners often expect but this is not guaranteed. See [this answer](https://stackoverflow.com/a/43420503/238704) for more details. – President James K. Polk Feb 15 '21 at 13:01