This took me longer than it should have. I am putting it here in the hopes that this post will spare others from having to Google things for extended periods of time.
In short, you either listen for a connection (Chat_Server), or connect to a remote IP address (Chat_Client). From there, you can send text strings back and forth.
This is a bit rough-hewn, obviously; I apologize in advance.
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 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | #!usr/bin/env python
import socket
import threading
import select
import time
def main():
class Chat_Server(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.running = 1
self.conn = None
self.addr = None
def run(self):
HOST = ''
PORT = 1776
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST,PORT))
s.listen(1)
self.conn, self.addr = s.accept()
# Select loop for listen
while self.running == True:
inputready,outputready,exceptready \
= select.select ([self.conn],[self.conn],[])
for input_item in inputready:
# Handle sockets
data = self.conn.recv(1024)
if data:
print "Them: " + data
else:
break
time.sleep(0)
def kill(self):
self.running = 0
class Chat_Client(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.host = None
self.sock = None
self.running = 1
def run(self):
PORT = 1776
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.connect((self.host, PORT))
# Select loop for listen
while self.running == True:
inputready,outputready,exceptready \
= select.select ([self.sock],[self.sock],[])
for input_item in inputready:
# Handle sockets
data = self.sock.recv(1024)
if data:
print "Them: " + data
else:
break
time.sleep(0)
def kill(self):
self.running = 0
class Text_Input(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.running = 1
def run(self):
while self.running == True:
text = raw_input('')
try:
chat_client.sock.sendall(text)
except:
Exception
try:
chat_server.conn.sendall(text)
except:
Exception
time.sleep(0)
def kill(self):
self.running = 0
# Prompt, object instantiation, and threads start here.
ip_addr = raw_input('What IP (or type listen)?: ')
if ip_addr == 'listen':
chat_server = Chat_Server()
chat_client = Chat_Client()
chat_server.start()
text_input = Text_Input()
text_input.start()
elif ip_addr == 'Listen':
chat_server = Chat_Server()
chat_client = Chat_Client()
chat_server.start()
text_input = Text_Input()
text_input.start()
else:
chat_server = Chat_Server()
chat_client = Chat_Client()
chat_client.host = ip_addr
text_input = Text_Input()
chat_client.start()
text_input.start()
if __name__ == "__main__":
main()
|
Defaults to port 1776, but can be changed fairly easily (note must be changed in two locations).
Looks great, teddy_k. May I suggest a few things to refine this?
there is a lot of redundant code that could be modularized. For example, both your chat server and client have lines that are the exact same, and could be placed into its own function called handle_sockets() or something, passing in inputready:
you check for 'listen' and 'Listen', and repeat the same code twice. Why not just do an case insensitive string check?
the if statements should not have repeated code in both (seeing a pattern here?). I would move these lines outside of the conditionals so that it looks like this:
Thank you for taking the time to reply, Matthew. I greatly appreciate the feedback.
Your observations are all correct; much of the code is redundant, the 'if' statements should be clearer, and a global variable would make changing the port simpler.
May I have permission to include your improvements in the above MIT-licensed code (with attribution, of course)? If not OK, I understand--I only ask because your changes would represent a significant improvement to what I cobbled together.
Thanks, teddy_k
I just wanted to see how it runs and get this error.
File "test.py", line 32 print "Them: " + data ^ SyntaxError: invalid syntax
Got it working looks like I was using 3.2 where the print statement has been changed. Works fine on 2.7. thanks for all your work teddy_k