python server rådgivning behövs :)

Här diskuteras programmering och utveckling
Användarvisningsbild
BadOmen
Inlägg: 1172
Blev medlem: 18 aug 2006, 10:45
OS: Kubuntu
Utgåva: 24.04 Noble Numbat LTS
Ort: Umeå

python server rådgivning behövs :)

Inlägg av BadOmen »

Jag startar med frågan så får ni läsa en förklaring av problemet nedan.
Ska jag köra en TCP server på både mobilen och datorn eller ska jag bara köra en server på datorn? Gärna nåt tips på hur jag ska lägga upp det :)

Jag har testat lite olika typer av sätt att sätta upp servrar på både via import socket och via
import socketserver men jag har ingen aning om vad som skulle vara bäst för mig... Så jag skulle också vilja veta om det spelar nån roll vad jag använder och om jag skulle ha nån fördel av den ena eller den andra?

Här är förklaringen till problemet:

Jag har en client utan GUI i min mobil som skickar sms till en server i datorn som har ett GUI (tkinter) där jag tar hand om smset och skriver ett eget svar tillbaka till clienten i mobilen som vidare skickar det som sms. (Jag skickar alltså ett svar till baka till mobilen efter att jag har skrivit meddelandet i tkinter och tryckt på send)

På datorn kör jag tkinter som main thread och servern som en egent thread.
Kommunicationen där emellan funkar genom att jag använder en
sendQ = queue.Queue()
reciveQ = queue.Queue()

GUIet tar emot data från clienten(mobilen) via reciveQ och skickar data till mobilen via sendQ.

Det funkar hyfsat problemet är att för att få servern att sända till clienten från sendQ så måste servern sluta läsa från clienten och det gör den bara varje gång som clienten har skickat nått klart. Så för att jag ska få servern att läsa från sendQ så måste jag se till att clienten skickar en tom string med jämna mellanrum.

Jag har även försökt att använda select.select och modiferat sockten till att vara WRITE i stället för READ men det blir ju samma problem där...

Måste jag sätta upp en server på mobilen också? och ansluta till den automtiskt efter att jag har fått en connection med mobilen och i och med det även reda på dennes ip.

Helst vill jag inte ha nån server på mobilen även om jag kanske skulle kunna se till att ingen får koppla upp mot servern på mobilen fören mobilen själv har kopplat upp sig mot datorn. Hur som helst blir det bökigt och jag måste skapa threads på mobilen också för att få det att funka på det viset.

Förövrigt så vet jag att säkerheten suger men appen jag har gjort på mobilen startar bara om jag är ansluten till mitt privata hemmanätverk, vilket är separat från gästnätverket... Men det här är möjligen ett senare problem, och inget jag vill ha hjälp med nu :)

EDIT:
Här är en förenklad version av det jag vill göra. Helt utan serverdel för det får jag ingen ordning på alls...
Det blir ett minimalt GUI ( en Exist och en Send knapp.) en thread som jag jag vill ska motsvara en tcp server. Men som nu tar emot medelande från GUI när man trycker på Send och samtidigt fortsätter att skicka meddelanden från "clienten" till Gui main thread.

Så Send meddelandet vill jag skicka till en server och meddelandena som genereras av threaden vill jag ska motsvara mottagna medelanden från en client och skickas nu till main threaden i gui.

Det är nog lättare att testa och att läsa koden än min förklaring...
Hur får jag det att funka med en tcpServer där? :-\
Eller finns det nått annat bättre sätt att göra det på?
Jag vill bara ha en client uppkopplad åt gången men om den stänger ned sig så ska den kunna koppla upp sig igen.

Kod: Markera allt

#!/usr/bin/python3.4
# -*- encoding:'utf-8' -*-
import tkinter as tk
import time
import threading
import random
import queue


class ThreadedGUI(tk.Tk):
    """
    Launch the main part of the GUI and the worker thread. periodicCall and
    endApplication could reside in the GUI part, but putting them here
    means that you have all the thread controls in a single place.
    """
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)     
        """Start the GUI and the asynchronous threads. We are in the main
        (original) thread of the application, which will later be used by
        the GUI as well. We spawn a new thread for the worker (I/O).
        """
        
        # Set up the GUI
        btnExit = tk.Button(self, text='Exit', command=self.endApplication)
        btnSend = tk.Button(self, text='Send', command=self.mySend)
        btnExit.pack()
        btnSend.pack()
        # Add more GUI stuff here depending on your specific needs
        # Create the queue
        self.reciveQ = queue.Queue()
        self.sendQ = queue.Queue()

      
        # Set up the thread to do asynchronous I/O
        # More threads can also be created and used, if necessary
        self.running = 1
        self.rand = random.Random()
        self.thread1 = threading.Thread(target=self.workerThread1)
        self.thread1.start()

        # Start the periodic call in the GUI to check if the queue contains
        # anything
        self.periodicCall()
    def mySend(self):
        """just a test so i can klick a button at the same time as the worker thread does it work..."""
        msg = "mesage from GUI to client"
        #msg = msg.encode() om den ska skickas till server, msg.decode('utf-8) på server sidan
        self.sendQ.put(msg)

    def processIncoming(self):
        """Handle all messages currently in the queue, if any."""
        while self.reciveQ.qsize():
            try:
                msg = self.reciveQ.get(0) 
                print("Message from Thread", msg) 

                
            except queue.Empty:
                # just on general principles, although we don't
                # expect this branch to be taken in this case
                pass
        

    def periodicCall(self):
        """
        Check every 200 ms if there is something new in the queue.
        """
        self.processIncoming()
        if not self.running:
            # This is the brutal stop of the system. You may want to do
            # some cleanup before actually shutting it down.
            app.quit()

        self.after(200, self.periodicCall)

    def workerThread1(self,):
        """
        This is where we handle the asynchronous I/O. For example, it may be
        a 'select(  )'. One important thing to remember is that the thread has
        to yield control pretty regularly, by select or otherwise.
        """
        while self.running:
            # To simulate asynchronous I/O, we create a random number at
            # random intervals. Replace the following two lines with the real
            # thing.
            time.sleep(self.rand.random() * 1.5)
            msg = self.rand.random()
            self.reciveQ.put(msg) # från 'client'

            if self.sendQ.qsize() > 0:
                fromGUI = self.sendQ.get(0)
                print(fromGUI)

    def endApplication(self):
        self.running = 0

if __name__ == "__main__":
    app = ThreadedGUI()
    app.mainloop()
Betygsätt din Hårdvara och underlätta inköp av ny för andra:http://ubuntu-se.org/phpBB3/viewforum.php?f=138
Ubuntu-se forsknings team, här.
Min Ubuntu blogg som funkar som en stor post-it lapp för mig http://attminnas.blogspot.com/

Återgå till "Programmering och webbdesign"