Domanda

Trying to make a simple python messager, getting quite aconnection unreachable error. I am trying to make it peer2peer. Could anyone also suggest how to make it better, I was thinking of adding a loop of some sort to ask the user for the next message, not sure how to go about doing this however.

Server.py

import socket

s = socket.socket()         
host = socket.gethostbyname(socket.gethostname())
port = 1337                
s.bind((host, port))        

s.listen(5)                 
while True:
   c, addr = s.accept()     
   print ("Got connection from", addr)
   c.send("Thank you for connecting to {0}".format(host).encode())
   msg1 = input("Enter Message: ")
   c.send(msg1.encode())
   msg2 = input("Enter Message: ")
   c.send(msg1.encode())
   msg3 = input("Enter Message: ")
   c.send(msg1.encode())
   msg4 = input("Enter Message: ")
   c.send(msg1.encode())

   c.close()                

Client.py

import socket               

s = socket.socket()         
host = "" 
port = 1337
s.bind((host, port))  

print("""
================================================================================
Welcome to Coder77's local internet message for avoiding surveillance by the NSA
================================================================================
The current soon to be encrypted server is {0}
""".format(host))

host = input("Please select the IP you would like to communicate to: ")
print("Now connecting to {0}....".format(host))

try:
      s.connect((host, port))
      s.listen(5)                 
      while True:
         c, addr = s.accept()     
         msg1 = input("Enter Message: ")
         c.send(msg1.encode())
         msg2 = input("Enter Message: ")
         c.send(msg1.encode())
         msg3 = input("Enter Message: ")
         c.send(msg1.encode())
         msg4 = input("Enter Message: ")
         c.send(msg1.encode())
except socket.error:
      print ("Host is unreachable")

input("Enter to lose")
s.close()               

Thanks.

È stato utile?

Soluzione

Simple server (reworked your code a bit):

from threading import *
import socket

s = socket.socket()         
host = socket.gethostbyname(socket.gethostname())
port = 1337
s.bind((host, port))
s.listen(5)

def getMainThread():
    for thread in enumerate(): # Imported from threading
        if thread.name == 'MainThread':
            return thread
    return None

class client(Thread):
    def __init__(self, socket, address):
        Thread.__init__(self)
        self.socket = socket
        self.address = address
        self.start() # Initated the thread, this calls run()

    def run(self):
        main = getMainThread()
        while main and main.isAlive():
            message = self.socket.recv(8192).decode('utf-8')
            self.socket.send(b"Got your message.. send another one!")
        self.socket.close()

while True:
   c, addr = s.accept()
   client(c, addr)

This server (altho yet basic) will handle multiple clients.

And here's a working client solution:

import socket               

print("""
================================================================================
Welcome to Coder77's local internet message for avoiding surveillance by the NSA
================================================================================
The current soon to be encrypted server is {0}
""".format(host))

host = input("Please select the IP you would like to communicate to: ")
print("Now connecting to {0}....".format(host))

sock = socket.socket()
try:
    sock.connect((host, 1337))
    while True:
        message = input("Enter Message: ")
        if message == 'quit':
            break
        sock.send(bytes(message, 'UTF-8'))
        recieved = sock.recv(8192).decode('utf-8')
        print('Server responded with:', recieved)
except socket.error:
     print ("Host is unreachable")

sock.close()

Short about the server. The point of a server is to handle multiple clients, this one will thanks to some basic threads. Each client that connects, gets accepted and then thrown into a thread (when you call client() it will initate it's own thread and the rest of the application will continue along side of that clients thread).

All client threads should die when the main thread dies, for instance if you throw a CTRL+C it shouold break but the error handling there needs more work, and you'll most likely end up with a "Socket already in use" because of lack of perfection in the cleanup department. But you get the idea and you'll have to learn to do some work yourself :)

The client, as long as you don't write "quit" it will first and for more connect to a server in the cleanest way possible, and will forever SEND+Recieve messages to and from the server, until (as mentioned) you write "quit". That will disconnect and end your program.

Now, All this does, is send a message to the server and it auto-replies. Consider creating something such as:

clients = {}
...
clients[self.addr[0]] = self.socket

or even

clients['Torxed'] = self.socket

Enabling yo to do stuff like:

message = self.socket.recv(8192).decode('utf-8')
toWho = message.split(': ', 1)[0]
if toWho in clients:
    clients[toWho].send(bytes(message, 'UTF-8'))

So that when a client writes 'Torxed: Hey whats up mate?' it will get redirected to that client socket. That's just a completely simple and plain idea to show you what you should or at least could do.

Things that might be confusing

I noticed you wrote s = ... and c = ... quite a lot.
And you had some double-socket thing going on in the client..? Calling things for what they are is usually good practice.. for instance, In the server you could call the socket server but never s. Or you just keep it clean and simple and call it socket in both ends except in some rair occations where you might create multiple server-instance sockets for whatever reason (bridging servers and what not).

And remember, the easier and short the solution is.. The more probable it is that you'll remember why and how you solved it. Don't go overboard on solutions.

Your server for instance, had about the same number of lines of code as my solution had (mine is not perfect i know), but i managed to squeeze in threading and if i/you wnated to also a "friendslist".. Take good use of loops, functions and stuff.. They'll save your life :)

Also note

That if you intend to use the socket as a client, you don't need to do s.bind(()) or s.listen(5), that's server-side properties.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top