I am trying to create a client server model using TCP in python for file sharing.

Viewed 166

There are 2 problems I am facing. 1. If try using the menu option 3 first, my client code doesnt run in a loop, but if I use another option say 1 or 2 first it will run in a loop the way it should. 2. On the server side I keep getting this error. line 71, in list_files_s server_s.send(path.encode()) OSError: [WinError 10057] A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied From my understanding we do not need to send an address when using TCP as part of the send. Please help if you can.

This is the code so far.

Client:

import socket
import sys
import os
import threading

IP = "127.0.0.1" #can be hardset to these values for testing
#IP = socket.gethostname()
port = 12000

if int(port) > 5000: # converts the string parameter to integer for comparison to check if it is greater than 5000
    port = int(port)
else:
    print("Port should be greater than 5000")
    sys.exit()

def client_menu(): # this function presents a menu to the user and in turn calls different functions

    print(" 1. Get files from the server \n 2. Put files on the server \n 3. List all files \n 4. Exit")
    c = input("Enter an option to perform an action: ")
    print("You entered: " + c) #user input drives the menu, it is sent to the server side as well to execute the required function
    choice = int(c)
    client_s.send(c.encode())

    if choice == 1:
        recv_from_server() # used to recieve files stored on the server

    if choice == 2:
        send_to_server() # used to send files from the client to the server

    if choice == 3: # used to see the list of all files in a directory
        list_files_c()

    if choice == 4: # used to exit the system
        print("You chose to exit")
        sys.exit()

    elif choice > 4: # tells the user incorrect prompt given
        print("Command not understood")
        sys.exit()

#funtion definitions for the functions used in the menu

def send_to_server():  # gets the current path to check if required files exist before opening the file to be read and sent to the server
    path = os.getcwd()
    fileName = "foo1.txt"
    if os.path.exists(fileName):
        print("Path exists, sending files")
        fo_c=open(fileName, 'rb')
        words=fo_c.read(102040)
        print(words)
        client_s.send(fileName.encode()) # sends the filedata alongwith the IP and port information to the server
        client_s.send(words)
        fo_c.close()
        print("File: " + fo_c.name + " is being sent")
    else:
        print("Path not found")

def recv_from_server():
    fileName  = client_s.recv(2048) # gets the file information from the server, opens it to read and then saves it
    print("Path found, recieving files")
    fo_c = open(fileName, 'wb')
    print(fo_c)
    words = client_s.recv(10240)
    print(words)
    fo_c.write(words)
    fo_c.close()
    print("File: " + str(fileName) + "has been recieved")
    print("Saved as received"+str(fileName))

def list_files_c(): # lists all the files in the directory where the user is
    #path = os.getcwd()
    path = client_s.recv(2048)
    if os.path.exists(path):
        print("Path received, the list of files is: ")
        padir = os.listdir(path)
        for file in padir:
            print(file)
    else:
        print("Path not found")


client_s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # creates a TCP socket to establish communication
client_s.connect((IP, port))
msg = ("Connected to the server")
print(msg)
#client_s.send(msg.encode())
#msg = client_s.recv(2048)
#print(msg.decode())
while True:
    #client_menu()
    threading.Thread(target=client_menu(), args=(client_s,)).start()

Server:
import socket
import sys
import os

port = 12000 #can be hardset to this value for testing
IP = "127.0.0.1"
#IP = socket.gethostname()

if int(port) > 5000: # converts the string parameter to integer for comparison to check if it is greater than 5000
    port = int(port)
else:
    print("Port should be greater than 5000")
    sys.exit()

def server_menu():

    c = msg.recv(2048) # recieves the option selected by the user to execute the specified function call

    choice = int(c)

    if choice == 1:
        send_to_client() # used to send files to the client

    if choice == 2:
        recv_from_client() # used to receive files from the client

    if choice == 3:
        list_files_s() # used to print a list of files in the directory

    if choice == 4: # used to exit the system
        print("You chose to exit")
        sys.exit()

    elif choice > 4: # used to notify user of incorrect prompt
        print("Command not understood")
        sys.exit()

# definitions of the functions executed by the menu

def send_to_client():  # used to check if a file exists, then open to read before sending the encoded filedata
    fileName = "foo3.txt"
    if os.path.exists(fileName):
        print("Path found, getting file from the client")
        fo_s = open(fileName, 'rb')
        words = fo_s.read(10240)
        print(words)
        server_s.send(fileName.encode())
        server_s.send(words)
        fo_s.close()
        print("File: "+ fo_s.name +"is being sent")

    else:
        print("Path not found")

def recv_from_client():
    fileName = server_s.recv(2048) # recieves the file information from the client over a certian port and IP
    print("Path found, receiving files")
    fo_s = open(fileName, 'wb')     # opnes the files, and then saves it
    print(fo_s)
    words = server_s.recv(10240)
    print(words)
    fo_s.write(words)
    fo_s.close()
    print("File: " + str(fileName) + "has been received")
    print("Saved as received_"+str(fileName))

def list_files_s():     # sends directory path for lisiting on client side
    path = os.getcwd()
    if os.path.exists(path):
        print("Path found, sending path: " , path)
        server_s.send(path.encode())
    else:
        print("Path not found")


server_s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # creates a UDP socket
server_s.bind((IP, port))                           
server_s.listen(5)
print ("The server is ready to recieve from port:", port)

while True:
    msg, clientAddr = server_s.accept()
    data = msg.recv(2048)
    #msg1 = "Hello"
    #msg, clientAddr = server_s.recv(2048)
    #server_s.send(msg1.encode()) # sends the encoded string input by the user
    while True:
        server_menu()
1 Answers

This solution helps you solve [WinError 10057]

while True:
    msg, clientAddr = server_s.accept()
    data = msg.recv(2048)

The client socket is actually stored in msg of your code.

print("Path found, sending path: " , path)
server_s.send(path.encode())

But you are trying to send messages to the server socket, which makes no sense, and client would receive nothing, so you need to change server_s to msg if you need to recv or send from/to client.

Related