Search code examples
python-3.xfile-transferlan

How to fix windows decline error for lan file transfer


I'm a 14 year old beginner in software design but have good knowledge in python basic and acute amounts in networking. i recently got a raspberry pi 3 b+ brand new and am trying to make a python program that will allow me to transmit information input from my hp PC to my pi so it can display the info, this project is to help me with school, i have code typed and it runs but when i try to run the "client code", this is so my pi can receive the input data, i get an error saying that the device has declined my connection request, what should i do to fix the issue? if you want to see the code i can post it, but i'm not sure if that is necessary.

i only tried changing the port number in both programs, since that is not the issue and i' new to LAN and networking, i haven't tried anything else.

as requested my code is:(not HTML, CSS, or HTML. it's just easier to use that interface.

# send.py

import socket                   # Import socket module

port = 60000                    # Reserve a port for your service.
s = socket.socket()             # Create a socket object
host = socket.gethostname()     # Get local machine name
s.bind((host, port))            # Bind to the port
s.listen(5)                     # Now wait for client connection.

print 'Server listening....'

while True:
    conn, addr = s.accept()     # Establish connection with client.
    print 'Got connection from', addr
    data = conn.recv(1024)
    print('Server received', repr(data))

    filename='mytext.txt'
    f = open(filename,'rb')
    l = f.read(1024)
    while (l):
       conn.send(l)
       print('Sent ',repr(l))
       l = f.read(1024)
    f.close()

    print('Done sending')
    conn.send('Thank you for connecting')
    conn.close()


# recieve.py

import socket                   # Import socket module

s = socket.socket()             # Create a socket object
host = socket.gethostname()     # Get local machine name
port = 60000                    # Reserve a port for your service.

s.connect((host, port))
s.send("Hello server!")

with open('received_file', 'wb') as f:
    print 'file opened'
    while True:
        print('receiving data...')
        data = s.recv(1024)
        print('data=%s', (data))
        if not data:
            break
        # write data to a file
        f.write(data)

f.close()
print('Successfully get the file')
s.close()
print('connection closed')


Solution

  • Unfortunately, this answer requires Python 3.5+.

    Before running this code please make sure you've worked out which IP you will be using for your server and client (help at the bottom).

    Step 1 - Ensure a simple ping works

    Server code:

    import socket
    
    # FIND IP
    
    # The IP to use will be different depending
    # on whether you have WiFi or Ethernet, so
    # you need to choose whichever one that is
    ips = socket.gethostbyname_ex(socket.gethostname())[-1]
    
    print(*[f"{i}: {j}" for i, j in enumerate(ips)], sep="\n")
    
    ip = ips[int(input(" > "))]
    
    # SELECT PORT
    
    port = 10000
    
    
    #SETUP SERVER
    
    # Create server socket
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind((ip, port))
    
    # A queue of 1 clients is more than enough for our application
    sock.listen(1)
    
    print(f"Listening on {ip}:{port}")
    
    while True:
        try:
            (clientsock, address) = sock.accept()
    
            # so if there's nothing to read we don't wait too long
            clientsock.settimeout(0.01)
    
            ping_string = clientsock.recv(5).decode()
    
            if ping_string == "ping!":
                print("ping!")
    
                clientsock.sendall(b"ping!")
    
            else:
                print("no ping!")
                print(ping_string)
    
                clientsock.sendall(b"nopng")
    
            clientsock.shutdown(1)
            clientsock.close()
    
        except KeyboardInterrupt:
            # Add a way to safely exit the infinite loop
            break
    
    sock.close()
    

    Client code:

    import socket
    
    # GET IP
    
    print("IP of server")
    ip = input(" > ")
    
    # SELECT PORT
    
    port = 10000
    
    
    # SETUP SOCKET
    
    # Create server socket
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((ip, port))
    
    print(f"Conencted to {ip}:{port}")
    
    # so if there's nothing to read we don't wait too long
    sock.settimeout(0.01)
    
    sock.sendall(b"ping!")
    
    ping_string = sock.recv(5).decode()
    
    if ping_string == "ping!":
        print("ping!")
    
    else:
        print("no ping!")
    
    sock.close()
    

    OUTPUT:

    Server:

    0: 192.168.56.1
    1: 192.168.1.151
     > 1
    Listening on 192.168.1.151:10000
    

    Client:

    Type ip of server
     > 192.168.1.151
    Conencted to 192.168.1.151:10000
    ping!
    

    If this doesn't work, make sure your computer can ping your raspberry pi, and vice versa. Go into CMD (I presume your HP PC is Windows) and type ping ____ (replacing ____ with the internal ip address of your raspberry pi.

    If the terminal doesn't appear to be pinging something, you need to go onto your computer and raspberry pi to find they're internal ips, which you can find out how to do online.

    Step 2 - The fun part

    We're now going to setup your file server.

    Server code:

    import socket
    
    # OPEN FILE TO SEND ACROSS
    with open("filesend.txt", mode="rb") as file:
        file_string = file.read()
    
    # FIND IP
    
    # The IP to use will be different depending
    # on whether you have WiFi or Ethernet, so
    # you need to choose whichever one that is
    ips = socket.gethostbyname_ex(socket.gethostname())[-1]
    
    print(*[f"{i}: {j}" for i, j in enumerate(ips)], sep="\n")
    
    ip = ips[int(input(" > "))]
    
    # SELECT PORT
    
    port = 10000
    
    
    #SETUP SERVER
    
    # Create server socket
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind((ip, port))
    
    # A queue of 1 clients is more than enough for our application
    sock.listen(1)
    
    print(f"Listening on {ip}:{port}")
    
    while True:
        try:
            (clientsock, address) = sock.accept()
    
            # so if there's nothing to read we don't wait too long
            clientsock.settimeout(0.01)
    
            # send length
            clientsock.sendall((str(len(file_string)) + ".").encode())
            clientsock.sendall(file_string)
    
            print("Sent file!")
    
            response_code = clientsock.recv(1).decode()
    
            if response_code != "0":
                print("ERROR! response was not 0")
                print(response_code)
    
    
            clientsock.shutdown(1)
            clientsock.close()
    
        except KeyboardInterrupt:
            # Add a way to safely exit the infinite loop
            break
    
    sock.close()
    

    Client code:

    import socket
    
    # SELECT IP
    
    print("IP of server")
    ip = input(" > ")
    
    # SELECT PORT
    
    port = 10000
    
    
    # SETUP SOCKET
    
    # Create server socket
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((ip, port))
    
    print(f"Conencted to {ip}:{port}")
    
    # so if there's nothing to read we don't wait too long
    sock.settimeout(0.01)
    
    # Get length of file sent across
    len_string = ""
    c = ""
    while c != ".":
        c = sock.recv(1).decode()
        len_string += c
    
    length = int(len_string[:-1])
    
    file_string = sock.recv(length)
    
    # send a status code back to the server
    sock.sendall(b"0")
    
    with open("filerecv.txt", mode="wb") as file:
        file.write(file_string)
    
    print(file_string.decode())
    
    sock.close()
    

    OUTPUT:

    Server:

    0: 192.168.56.1
    1: 192.168.1.151
     > 1
    Listening on 192.168.1.151:10000
    

    Client:

    IP of server
     > 192.168.1.151
    Conencted to 192.168.1.151:10000
    THIS IS A TEST!
    

    Once again, ensure the ip you tell the client to connect to is the same as the one you have selected from the list provided in the server script. Also ensure that the ip address can be connected to, ie don't use the one for when the pc's on WiFi if it's currently on Ethernet.

    Hope this works for you. Any issues leave down in the comments :)

    EDIT

    WINDOWS

    Sample output from ipconfig:

    > ipconfig
    
    Windows IP Configuration
    
    
    Ethernet adapter Ethernet:
    
       Connection-specific DNS Suffix  . : home
       IPv6 Address. . . . . . . . . . . : 2a00:23c6:6586:2400:e47a:c60e:812b:1123
       IPv6 Address. . . . . . . . . . . : fdaa:bbcc:ddee:0:e47a:c60e:812b:1123
       Temporary IPv6 Address. . . . . . : 2a00:23c6:6586:2400:d1fe:95f5:27c3:c4b8
       Temporary IPv6 Address. . . . . . : fdaa:bbcc:ddee:0:d1fe:95f5:27c3:c4b8
       Link-local IPv6 Address . . . . . : fe80::e47a:c60e:812b:1123%19
       IPv4 Address. . . . . . . . . . . : 192.168.1.151
       Subnet Mask . . . . . . . . . . . : 255.255.255.0
       Default Gateway . . . . . . . . . : fe80::8aa6:c6ff:fe23:7a15%19
                                           192.168.1.254
    

    You're looking for this line:

       IPv4 Address. . . . . . . . . . . : 192.168.1.151
    

    And the IP is whatever value is at the end (eg 192.168.1.151)

    FIND THE IP OF YOUR RASPBERRY PI

    Unless you've changed some advanced settings your Raspberry Pi's hostname will be raspberrypi, or raspberrypi.local. I've seen both. If you want to know the IP address, use the Python script below, and try to ping all the IPs from the list it prints to find out which one IP is actually used by the Pi.

    Run this on your PC:

    import socket
    
    host1 = "raspberrypi"
    host2 = "raspberrypi.local"
    
    try:
        ip1 = socket.gethostbyname_ex(host1)[-1]
    except:
        ip1 = []
    
    try:
        ip2 = socket.gethostbyname_ex(host2)[-1]
    except:
        ip2 = []
    
    print(list(set(ip1+ip2)))
    

    Any more issues, please let me know :)