How to make xender app using socket and kivy in python



it is the project for file sending app which is made in python using socket [backend] and kivy [frontend]
This project is made for making file sender app using python programming.
It has two two folders **server** and **client** and both folders have same files.
if you'll convert this app as android project (*apk file*) , then you won't need both folders.
just remove one of them and move another's files in master branch and make your app.

requrements
1. Python 3.x
2. socket module (no need to install )
3. kivy (pip install kivy)
4. basic knowledge of python
**How to run this project**
To test it's working, download/clone this repo and open-
server folder and run gui_app.py
after that, open client folder and run gui_app.py
in both gui screens, two buttons are available send and receive
click recieve on one and send on another (make sure you first click on receive )
It will ask in console for :
Enter hash type: type anything here
Enter file(s) to send: pass ur files u want to send (ex. file1.png c:/user/.../desktop/file.mp4)

You can freely use this app project .
you can make it's apk with buildozer




server/buffer.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class Buffer:
    def __init__(self,s):
        '''Buffer a pre-created socket.
        '''
        self.sock = s
        self.buffer = b''

    def get_bytes(self,n):
        '''Read exactly n bytes from the buffered socket.
           Return remaining buffer if <n bytes remain and socket closes.
        '''
        while len(self.buffer) < n:
            data = self.sock.recv(1024)
            if not data:
                data = self.buffer
                self.buffer = b''
                return data
            self.buffer += data
        # split off the message bytes from the buffer.
        data,self.buffer = self.buffer[:n],self.buffer[n:]
        return data

    def put_bytes(self,data):
        self.sock.sendall(data)

    def get_utf8(self):
        '''Read a null-terminated UTF8 data string and decode it.
           Return an empty string if the socket closes before receiving a null.
        '''
        while b'\x00' not in self.buffer:
            data = self.sock.recv(1024)
            if not data:
                return ''
            self.buffer += data
        # split off the string from the buffer.
        data,_,self.buffer = self.buffer.partition(b'\x00')
        return data.decode()

    def put_utf8(self,s):
        if '\x00' in s:
            raise ValueError('string contains delimiter(null)')
        self.sock.sendall(s.encode() + b'\x00')

server/methods.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import socket
import os

import buffer
def send():
    HOST = '127.0.0.1'
    PORT = 2345
    connection = False
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    c = s.connect((HOST, PORT))
    print(c)

    with s:
        sbuf = buffer.Buffer(s)

        hash_type = input('Enter hash type: ')

        files = input('Enter file(s) to send: ')
        files_to_send = files.split()

        for file_name in files_to_send:
            print(file_name)
            sbuf.put_utf8(hash_type)
            sbuf.put_utf8(file_name)


            file_size = os.path.getsize(file_name)
            print("{:.2f} MB".format(file_size/(1024*1024)))
            sbuf.put_utf8(str(file_size))

            with open(file_name, 'rb') as f:
                sbuf.put_bytes(f.read())
            print('File Sent')

def recieve():
    HOST = ''
    PORT = 2345

    # If server and client run in same local directory,
    # need a separate place to store the uploads.
    try:
        os.mkdir('downloads')
    except FileExistsError:
        pass

    s = socket.socket()
    s.bind((HOST, PORT))
    s.listen(10)
    print("Waiting for a connection.....")

    while True:
        conn, addr = s.accept()
        print("Got a connection from ", addr)
        connbuf = buffer.Buffer(conn)

        while True:
            hash_type = connbuf.get_utf8()
            if not hash_type:
                break
            print('hash type: ', hash_type)

            file_name = connbuf.get_utf8()
            file_size = int(connbuf.get_utf8())
            if not file_name or not file_size:
                print("Wrong file or connection closed.")
                break
            file_name = file_name.split('/')[-1]
            file_name = os.path.join('downloads/',file_name)
            print('file name: ', file_name) 
            print('file size: {:.2f} MB'.format(file_size/(1024*1024)))

            with open(file_name, 'wb') as f:
                remaining = file_size
                while remaining:
                    chunk_size = 4096 if remaining >= 4096 else remaining
                    chunk = connbuf.get_bytes(chunk_size)
                    if not chunk: break
                    f.write(chunk)
                    remaining -= len(chunk)
                    #print("\rSent: {:.2f} MB".format((file_size-remaining)/(1024*1024)))
                if remaining:
                    print('File incomplete.  Missing',remaining,'bytes.')
                else:
                    print('File received successfully.')
        print('Connection closed.')
        conn.close()

if __name__ == "__main__":
    ask = int(input("What do you want?\n1. Send\n2. Recieve\n\n"))
    if ask is 1:
        send()
    elif ask is 2:
        recieve()

server/gui_app.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
#from kivy.uix.dialog import Dialog
from methods import send,recieve
class I_Xender(App):

    def build(self):

        vlayout = BoxLayout(orientation='vertical')
        # Create a button for taking photograph
        hlayout = BoxLayout(orientation='horizontal')
        self.sendButton = Button(text="Send",
                                 font_size=30,
                                 color=(0,0,50,50),
                                 background_normal = 'send.png', 
                                 background_down ='recv.png',
                                 size_hint=(.2,.2),
                                 border=(0,0,0,0),
                                 pos_hint={'x': .1, 'y':.2},
                                 )
        # bind the button's on_press to onCameraClick
        self.sendButton.bind(on_press=self.sendFiles)
        # add send button to the hlayout

        self.recieveButton = Button(text="Recieve",
                                    font_size=30,
                                    color=(0,0,50,50),
                                    background_normal = 'recv.png', 
                                    background_down ='send.png',
                                    size_hint=(.2,.2),
                                    border=(0,0,0,0),
                                    pos_hint={'x': .6, 'y':.2}, 
                                    )
        # bind the button's on_press to onCameraClick
        self.recieveButton.bind(on_press=self.recvFiles)

        # add send button to the hlayout        
        hlayout.add_widget(self.sendButton)
        hlayout.add_widget(self.recieveButton)

        #now add hlyout to layout
        vlayout.add_widget(hlayout)
        # return the root widget
        return vlayout

 

    # Take the current frame of the video as the photo graph       

    def sendFiles(self, *args):
        send()
    def recvFiles(self, *args):
        recieve()
            
        

       

       

# Start the Camera App

if __name__ == '__main__':
    I_Xender().run()
Watch full tutorial /explanation of code :


If you want it's advanced version with awesome working of gui with file chooser system, You can contact me.
Email: cidaneducationhub@gmail.com
Message on : m.me/CIDanPawan    or m.me/cideduhub
**------------------------------------------------------------------**
If you realized this project helpful for you
You can  donate me on:
https://www.paypal.me/cideduhub
or, UPI ID : cidaneducationhub@oksbi

Comments

Post a Comment

Popular posts from this blog

Make CCTV Camera Software using Python || AI and Machine learning tutori...

Drowsiness detection system using openCV in python

Make Barcode Scanner using Python