k33theod Δημοσ. 24 Απριλίου 2016 Μέλος Δημοσ. 24 Απριλίου 2016 Επειδη μαρεσεις θα σου γραψω εναν σερβερ. Εσυ θα γραψεις μετα τον client, και μετα τον server. Βημα 1ο: Φτιαχτικε το github https://github.com/AnonymoPapaki/SimpleChatServer ωρα 12:43 Βημα 2ο: Αρχικο σχημα https://github.com/AnonymoPapaki/SimpleChatServer/commit/d777a77cd21c25e4df13a7f1f13504068123ff74 ωρα 1:38 Κι εσύ μ'αρέσεις, μόλις όμως βγήκα από μία σχέση και δεν είμαι έτοιμος για κάτι τόσο σοβαρό .Έχω έτοιμο τον νέο server σε python. Θα τον ανεβάσω κάποια στιγμή.
παπι Δημοσ. 25 Απριλίου 2016 Δημοσ. 25 Απριλίου 2016 done εδω ειναι το exe SimpleChatServer.zip Ο σερβερ δουλευει με TCP και τα connections διαρκουν οσο η καθε socket ειναι connected, επισης ειναι full dublex και ασυγχρονο. Το προτοκολλο ειναι κατι σα εντολες. Δηλαδη.. Ο client εφοσον εχει γινει συνδεση σε socket level. Θα πρεπει να στειλει setName name$ οπου στο name βαζεις το ονομα που θες να εμφανιζεται. για να στειλει ενα μηνυμα σε ολους send all$message για να στειλει σε ενα ατομο send name$message Παραλληλα ο client θα πρεπει να περιμενει ενα απο αυτα τα μηνυματα list$ name1 name2 nameN Οπου μας λεει ποιοι ειναι συνδεδεμενοι. msg all sender name$ message Οπου μας λεει οτι ηρθε ενα μηνυμα και προοριζεται για ολους. το name εχει το ονομα του αποστολεα το message το μηνυμα msg pm sender name$ message Το ιδιο με το πανω, μου που προοριζεται για σενα μονο. αυτα ΥΓ ξεχασα, εχω 9090 port
k33theod Δημοσ. 26 Απριλίου 2016 Μέλος Δημοσ. 26 Απριλίου 2016 Ευχαριστώ, αυτά που λες με βοηθάνε για το πώς να προχωρήσω. Στην υλοποίησή τους όμως στη γλώσσα python, έχω πρόβληματα. Τώρα προσπαθώ να βρω πως θα απελευθερωνω τα socket με το κλείσιμο κάθε client. Στο βίντεο είδα ότι μπορείς να γράψεις εκεί που εμφανίζονται τα μυνήματα. Εγώ το έλυσα κάνοντας το παράθυρο disabled. και το κάνω normal πριν κάθε εγγραφή και μετά πάλι disabled. Δεν ξέρω το αντίστοιχο της c++. Αν δεις το script μου είναι 3 γραμμές κώδικα στον client.
k33theod Δημοσ. 26 Απριλίου 2016 Μέλος Δημοσ. 26 Απριλίου 2016 (επεξεργασμένο) Αυτή είναι λοιπόν η πολυαναμένομενη version1.1 Το μόνο που κάνει είναι ότι πέρνει το μύνημα κάθε client και το στέλνει σε όλους. # Ver. 1.1 # Το παρόν πρόγραμμα είναι ένας απλός server # Εισάγω τις απαραίτητες βιβλιοθήκες from socket import * import threading as t # Αυτή η συνάρτηση λαμβάνει και στέλνει δεδομένα # Τρέχει ξεχωριστά ως thread για κάθε connection (con) def receive_send(con): # Το πρώτο μύνημα που στέλνει μετά από τη σύνδεση connection_message='Καλωσήρθατε '+ str(len(connections))+' συνδεδεμένοι χρήστες\n' con.send(connection_message.encode('utf-8'))# Το κωδικοποιώ και το στέλνω while True: #βρόγχος που τρέχει πάντα data_recv=con.recv(1024) #ότι δεδομένα λαμβάνει for i in connections: #τα στέλνει σε όλους i.send(data_recv) con.close() def connector(): #Η συνάρτηση που κάνει τις συνδέσεις while True: # Τρέχει συνέχεια con, address = s.accept() #κάνει accept και επιστρέφει το con, address connections.append(con) # Βάζει το κάθε νέο con στον πίνακα των συνδέσεων #δημιουργώ thread για τη receive_send a=t.Thread(target=receive_send, args=(con,)) a.start()# Το ξεκινάω connections=[] # πίνακας συνδέσεων host='' # κενό port=8000 #port 0 έως 65535 Οι θύρες 0-1023 πρέπει να αποφεύγονται γιατί είναι δεσμευμένες # για διάφορες λειτουργίες, περισσότερα εδώ https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers s=socket() #normal socket, έχω παραλείψει τις παραμέτρους s.bind((host, port)) # Το κάνω bind με το tuple(host, port) s.listen(5) # Τρέχω τη συνάρτηση connector connector() Τον client τον έγραψα σε γραφικό περιβάλλον #Το παρόν πρόγραμμα είναι ένας client σε γραφικό περιβάλλον #που καλεί ένα σερβερ με την ip ή hostname, port και username #Εισάγω τις βιβλιοθήκες from socket import * from tkinter import * from tkinter import ttk import time import threading as t s=socket()#Δημιουργώ ένα socket #Δίνω αρχικές τιμές στις μεταβλητές μου host='' port=0 name='' #Η συνάρτηση που στέλνει τα δεδομένα def send_message(event): str_message= name + ': ' + entry_client.get() + '\n' #Το μύνημα το οποίο περιέχει #το όνομα και αυτά που γράψαμε στο entry data_send=str_message.encode() #κάνουμε encode s.send(data_send) #το στέλνουμε entry_client.delete(0,END) #μηδενίζω τα στοιχεία του entry def receive(): #Η συνάρτηση που λαμβάνει και τυπώνει τα μυνήματα στο text while True: #Τρέχει συνέχεια data_recv=s.recv(1024) #λαμβάνει data_str_recv=data_recv.decode('utf-8') #κάνει decode message_place.config(state=NORMAL) #αλλάζει το status του text για να μπορώ να γράψω ora=time.strftime('%H:%M:%S ',time.localtime()) #παίρνω την τρέχουσα ώρα if data_str_recv.startswith(name): #Αν το μύνημα αρχίζει με το όνομά μου που σημαίνει ότι είναι δικό μου message_place.insert(END,ora+''+data_str_recv,'me') #το τυπώνω με άλλο χρώμα else: message_place.insert(END,ora+data_str_recv) #αλλίως το τυπώνω μαύρο message_place.config(state=DISABLED) #ξανα αλλάζω το state του text # Η συνάρτηση που κάνει τη σύνδεση με το server def connect(): global name,host,port,s #Δίνω νέες τιμές στις μεταβλητές μου name=entry_name.get() win.title(name) host=entry_ip.get() server_host=host port=entry_port.get() port=int(port) s.connect((server_host, port)) #κάνω τη σύνδεση με το tuple (server_host, port) a=t.Thread(target=receive) #δημιουργώ thread για τη receive a.start() #και το ξεκινάω # Απο εδώ και κάτω το γραφικό περιβάλον win=Tk() win.title('CLIENT') frame1=Frame(win) frame1.pack(expand=True, fill='both', side='top') # Το Text όπου γράφονται πληροφορίες σύνδεσεις και όλα τα μυνήματα message_place=Text(frame1, wrap=WORD) message_place.grid(row=0, column=0, columnspan=7,sticky='W', padx=5, pady=5) message_place.config(state=DISABLED) # Το απενεργοποιώ για να μην μπορώ να γράψω message_place.tag_configure('me', foreground='blue') #Κάνω tag με άλλο χρώμα για να το #χρησιμοποιήσω για τα μυνήματά μου frame2=Frame(win) frame2.pack(expand=True, fill='both') # label και entry για τα μυνήματα που γράφω. label_client=Label(frame2, text='Message: ') label_client.grid(row=0,column=0,sticky='W',padx=5,pady=5) entry_client=Entry(frame2, width=60) entry_client.grid(row=0,column=1, sticky='W',padx=5,pady=5) entry_client.bind("<Return>", send_message) #Με enter καλώ τη συνάρτηση που στέλνει το μύνημα frame3=Frame(win) frame3.pack(expand=True, fill='both') # label και entry για την IP. label_ip=Label(frame3, text='IP: ', bg='white') label_ip.pack(side='left',padx=5,pady=5) entry_ip=Entry(frame3,width=20) entry_ip.pack(side='left',padx=5,pady=5) # label και entry για τo port. label_port=Label(frame3, text='Port: ', bg='white') label_port.pack(side='left',padx=5,pady=5) entry_port=Entry(frame3) entry_port.pack(side='left',padx=5,pady=5) # label και entry για τo name label_name=Label(frame3, text='Your name: ', bg='white') label_name.pack(side='left',padx=5,pady=5) entry_name=Entry(frame3) entry_name.pack(side='left',padx=5,pady=5) rec_button=ttk.Button(frame3, text='connect', command=connect) # Το κουμπί για τη σύνδεση rec_button.pack(side='left', padx=5, pady=5 ) win.mainloop() και το αποτέλεσμα που πήρα μόνος μου online όπως foto Επεξ/σία 26 Απριλίου 2016 από k33theod
pmav99 Δημοσ. 26 Απριλίου 2016 Δημοσ. 26 Απριλίου 2016 port=8000 #port 0 έως 65535 Tα ports 0-1024 θέλουν sudo
k33theod Δημοσ. 26 Απριλίου 2016 Μέλος Δημοσ. 26 Απριλίου 2016 Tα ports 0-1024 θέλουν sudo Ναι, και άλλα comments είναι λάθος όπως αυτά στις γραμμές 44 και 96 στον client. Θα τα διορθώσω
Dr.Fuzzy Δημοσ. 26 Απριλίου 2016 Δημοσ. 26 Απριλίου 2016 Άσχετο, αλλά αυτό το "Το παρώον" διόρθωσε το γιατί βγάζει μάτια!
k33theod Δημοσ. 26 Απριλίου 2016 Μέλος Δημοσ. 26 Απριλίου 2016 Άσχετο, αλλά αυτό το "Το παρώον" διόρθωσε το γιατί βγάζει μάτια! Γιατί το τρέχουσα όρα τι κάνει, αφού και γώ που το είδα στραβώθηκα Δυστηχώς το notepad++ που χρησιμοποιώ δεν κάνει ορθογραφικό έλεγχο και δεν περνάω μετά το κείμενο από κάποιο έλεγχο με ελληνικό ορθογράφο οπότε ξεφεύγουν αρκετά λάθη. 1
giorgos147 Δημοσ. 9 Ιουνίου 2016 Δημοσ. 9 Ιουνίου 2016 (επεξεργασμένο) Αναπτύσσω και εγώ ένα chat και δυστυχώς αντιμετωπίζω ένα σοβαρό πρόβλημα. Έχω αφιερώσει > 7-8 ώρες και ακόμη δεν μπορώ να βγάλω άκρη. Δυστυχώς κώδικα δεν μπορώ να παραθέσω αυτή τη στιγμή (ίσως αφού δώσω το μάθημα ). Θα αναφέρω τι γίνεται και αν έχει κάποιος άποψη έστω στο περίπου, θα με έσωζε. Πραγματικά δεν πάει άλλο. Λοιπόν: Ανοίγουμε σέρβερ, συνδέουμε τον πρώτο client (ας τον πούμε client_1 για ευκολία). Όλα καλά. Στέλνει μηνύματα χωρίς πρόβλημα (τα βλέπει μόνο αυτός - δεν υπάρχει άλλος client στον chat server). Μπαίνει ο δεύτερος (client_2). Μια χαρά κιαυτός. Μπορεί να στείλει όσα θέλει. Όταν όμως ο client_1 στείλει ξανά, δεν μπορεί να στείλει παραπάνω μηνύματα από 1! Αφού, δηλαδή, συνδεθεί ο client_2, ο client_1 μπορεί να στείλει μόλις ένα μήνυμα (άλλες φορές και κανένα.... Δεν έχω προσδιορίσει ακριβώς πώς και πότε συμβαίνει αυτό). Το socket του client_1 όμως, αφού στείλει το μοναδικό μήνυμα που μπορεί μετά τη σύνδεση του client_2, δεν αποσυνδέεται. Τα μηνύματα του client_2 τα λαμβάνει όλα κανονικά. Γενικά, παρατήρησα ότι: ο client_1 στέλνει τα μηνύματα στον server, αλλά αυτός δεν τα βλέπει. Δεν "ακούει" ότι του στέλνουν κάτι. Αν κατάλαβε κανείς τίποτα από τα παραπάνω και έχει καμία ιδέα απλώς, ας την αναφέρει. Ξέρω είναι ανόητο χωρίς ούτε δείγμα κώδικα, αλλά ακόμη και μία ιδέα ίσως φανεί χρήσιμη. Edit: Όλα, μέχρι χθες το βράδυ που το άφησα, λειτουργούσαν μια χαρά. Σήμερα πρόσθεσα επιπλέον λειτουργίες και κάπου χάλασε η δουλειά. Φυσικά μπακ-απ αρχείο δεν υπάρχει (υπάρχουν, αλλά είναι αρκετά παλιά...), οπότε ψάχνω χωρίς κανένα όφελος μέχρι στιγμής. Και πάλι βέβαια, τα features που πρόσθεσα σήμερα δεν έχουν σχέση ρε γαμώτη με το συγκεκριμένο πρόβλημα. Edit 2: Όσο έπαιζα με lists, όλα θυμάμαι πως δούλευαν ρολόι. Το πρόβλημα ξεκίνησε όταν αντικατέστησα τις lists με dictionaries. Edit 3: Τσέκαρα και με wireshark. Τα πακέτα φτάνουν μέχρι τον σερβερ. Αυτός όμως δεν νιώθει. Επεξ/σία 9 Ιουνίου 2016 από giorgos147
defacer Δημοσ. 9 Ιουνίου 2016 Δημοσ. 9 Ιουνίου 2016 Αυτό ακούγεται σα να έχεις κάποιο bug στη λογική που διαβάζει ο server από τα sockets των clients. Μπορεί για παράδειγμα να έχεις μια μεταβλητή που κάπως αποθηκεύεται το socket που άνοιξε τελευταίο και να χρησιμοποιείς αυτήν μόνο κανονικά (οπότε ο τελευταίος client παίζει κανονικά ενώ οι προηγούμενοι όχι, ο server δεν ασχολείται μαζί τους). Ή μπορεί να βάζεις τα socket σε ένα πίνακα και να μην κάνεις select/read σε όλα παρά μόνο στο τελευταίο, ή κάτι along these lines. 1
giorgos147 Δημοσ. 9 Ιουνίου 2016 Δημοσ. 9 Ιουνίου 2016 Αυτό ακούγεται σα να έχεις κάποιο bug στη λογική που διαβάζει ο server από τα sockets των clients. Μπορεί για παράδειγμα να έχεις μια μεταβλητή που κάπως αποθηκεύεται το socket που άνοιξε τελευταίο και να χρησιμοποιείς αυτήν μόνο κανονικά (οπότε ο τελευταίος client παίζει κανονικά ενώ οι προηγούμενοι όχι, ο server δεν ασχολείται μαζί τους). Ή μπορεί να βάζεις τα socket σε ένα πίνακα και να μην κάνεις select/read σε όλα παρά μόνο στο τελευταίο, ή κάτι along these lines. Αυτό ήταν. Για να εξηγήσω: Στο σημείο που έστελνα σε όλους, είχα δηλώσει να διαβάζει από το dictionary την ίδια μεταβλητή με αυτή που τερματίζω το σοκετ, οπότε και μάλλον, όπως είπες, κράταγε τον τελευταίο. Τώρα βέβαια πώς μπορούσε να στείλει ακόμη ένα μήνυμα, είναι άγνωστο. Χίλια ευχαριστώ ρε συ. 1
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα