Where am I going wrong here. as far as i can tell this should work.
import socket, string
#some user data, change as per your taste
SERVER = 'irc.freenode.net'
PORT = 6667
NICKNAME = 'echoquote'
CHANNEL = '#python'
PASSWORD = 'nope'
import time
#open a socket to handle the connection
IRC = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#open a connection with the server
def irc_conn():
IRC.connect((SERVER, PORT))
#simple function to send data through the socket
def send_data(command):
IRC.send(command + '\n')
#join the channel
def join(channel):
send_data("JOIN %s" % channel)
#send login data (customizable)
def login(nickname, username='user', password = None, realname='Pythonist', hostname='Helena', servername='Server'):
send_data("USER %s %s %s %s" % (username, hostname, servername, realname))
send_data("NICK " + nickname)
send_data("nickserv identify %s %s\r\n" % (NICKNAME, PASSWORD))
time.sleep(3)
irc_conn()
login(NICKNAME)
join(CHANNEL)
while (1):
buffer = IRC.recv(1024)
msg = string.split(buffer)
message = ' '.join(msg[3:])
message = ''.join([x for x in message if x in string.printable])
if message:
print message + '\n'
if msg[0] == "PING": #check if server have sent ping command
send_data("PONG %s" % msg[1]) #answer with pong as per RFC 1459
if msg [1] == 'PRIVMSG' and msg[2] == NICKNAME:
filetxt = open('/tmp/msg.txt', 'a+') #open an arbitrary file to store the messages
nick_name = msg[0][:string.find(msg[0],"!")] #if a private message is sent to you catch it
message = ' '.join(msg[3:])
filetxt.write(string.lstrip(nick_name, ':') + ' -> ' + string.lstrip(message, ':') + '\n') #write to the file
filetxt.flush() #don't wait for next message, write it now!
send_data("nickserv identify %s %s\r\n" % (NICKNAME, PASSWORD))
There is no nickserv command in IRC. This is an alias in some IRC clients, and all it does is send a private message to NickServ. Read the IRC specification, and stop reinventing wheels — use an existing IRC library, eg. twisted.words, or an existing IRC bot solution.
Related
i have a client will send some string to my server. However, i need to send twice so that the server get the package. So for every package client wants to send the server, it needs to send twice. I do not understand why it went in this way.
my server's code that does listening:
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
myIp = "0x2A"
myPort = 2222
targetPort = 0
myAddress = ("localhost",myPort)
bufferSize = 1024
def listen():
print('starting up on {} port {}'.format(*myAddress))
sock.bind(myAddress)
# sock.listen(1)
print("waiting for message")
# connection, client_address = sock.accept()
while True:
received = sock.recvfrom(bufferSize)[0]
address = sock.recvfrom(bufferSize)[1]
received = json.loads(received.decode())
source = received.get("source")
destination = received.get("destination")
length = received.get("length")
message = received.get("message")
protocol = received.get("protocol")
print("the source is: " + source)
if destination == myIp:
print("the message is: " + message)
print('sending back to sender...')
sock.sendto(message.encode(),address)
if protocol == 0:
print("protocol is: " + str(protocol))
elif protocol == 1:
print("protocol is: " + str(protocol))
print("write data to log file....")
f = open("log.txt","w")
f.write(message)
print('done!')
elif protocol == 2:
print("protocol is: " + str(protocol))
# sock.close()
print("exit")
sock.close()
sys.exit()
else:
print("this is not my package: \n" + "destination Ip is: " + destination + "\n my Ip is: " + myIp)
if not received:
break
my client's code that does the sending:
def send():
try:
sock.sendto(message.encode(),serverAddress)
print("message: " + message + " is sent")
finally:
print('closing socket')
sock.close()
received = sock.recvfrom(bufferSize)[0]
address = sock.recvfrom(bufferSize)[1]
The first recvfrom will do the first read. The second recvfrom will do another read. Voila: you need two reads. Instead you should do a single read:
received, address = socket.recvfrom(bufferSize)
Me and a friend of mine are doing a chat room with python, basically he's doing the server part and I'm doing the GUI and Client part, I don't know why the app just stop to work without any reason showing the Windows message "Python is not responding"
This is the Server code:
#max name length=9999
#max message types=100
#max groupmsg recipients = 9999
#max msg length =8191 characters
import socket
import threading
import sys
def find_users(): #Continously Searches For New Clients
while True:
user, client_address = connector.accept()
threading.Thread(target=new_user, args=(user,)).start()
def new_user(identity):
while True:
print(identity)
name_length=identity.recv(4).decode() #max user name length =9999
username=identity.recv(int(name_length)).decode()
password=identity.recv(8192).decode()
if username in user_details and password == user_details[username]: #correct credentials
client_details[usename]=identity
identity.sendall('y'.encode())
break
elif username in user_details: #incorrect password
print('Please Re-enter The User Details')
identity.sendall('n'.encode())
else: #New user
user_details[username]=password
client_details[username]=identity
identity.sendall('y'.encode())
break
pubmsg(username+' has connected')
active_users.append(username)
identity.settimeout(5)
try:
while True: #waits for incoming messages
msgtype= identity.recv(2).decode() #identifies message type, max types =100
if msgtype == '01': #public message
communication = identity.recv(8192).decode()
pubmsg(str(username + ' >>> ' + communication))
elif msgtype == '02': #private message
direction=[]
recipno=identitiy.recv(4) #defines max group msg recipients
for y in range(0,recipno): #repeats once per recipient
recip_name_length=identity.recv(4).decode()
recip_name=identity.recv(recip_name_length).decode()
direction.append(recip_name)
gmsg=identity.recv(8192).decode()
groupmsg(gmsg,direction)
except Exception as e:
active_users.remove(username)
del client_details[username]
pubmsg(username+' disconnected')
identity.close()
sys.exit()
def pubmsg(Group_message):
print(Group_message)
for person in client_details:
client_details[person].sendall(Group_message.encode())
def groupmsg(Direct_message,recipients,sender):
gmsg=sender +' (to '
for person in recipients: #repeats once per recipient
gmsg+=person+', '
gmsg=gmsg.rstrip(', ')
gmsg=gmsg + ')' + ' >>> ' + Direct_message
for person in recipients:
client_details[person].sendall(gmsg)
user_details={}
client_details={}
active_users=[]
connector = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print ('Launching Server')
connector.bind(('localhost', 5000)) #Links socket to server address
connector.listen(10)
threading.Thread(target=find_users).start()
For the client and the GUI I'm putting here only the function called by the button "Connect" of the GUI (the ones that are creating problems), the GUI uses the QT Libraries
This is the code called by the button:
def client_connect(self):
ip_address = str(self.ipText.toPlainText())
port = int(self.portText.toPlainText())
nickname = self.nameText.toPlainText()
password = 'hello'
connect = threading.Thread(target = connection_thread, args = (ip_address, port, nickname, password))
connect.start()
This is the thread function:
def connection_thread(address, port, nickname, password):
nickname = nickname.encode()
password = password.encode()
while True:
try:
c = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
c.connect((address, port))
c.sendall('{0:0=4d}'.format(len(nickname)).encode())
c.sendall(nickname)
c.sendall(password)
answr = c.recv(2).decode()
if answr == 'y':
msg_box("CONNECTED", "Now you are connected to the server.")
while True:
time.sleep(2)
c.sendall('03'.encode())
message_received =c.recv(8192).decode()
self.chatList.addItem(message_received)
except Exception as e:
msg_box("CONNECTION FAILED", "Connection to server failed, try again.")
break
From the server code the connection of my client arrives but, the client stop working without showing the msg_box that says that we are connected.
When you say connect.join() you wait for the thread connect to finish, but it is in an infinite loop, so it is not done until the connection closes.
I am trying to make an irc bot. It connects but doesn't send the complete message. If I want to send "hello world" it only sends "hello". It just sends everything until the first space.
In this program if you type hello in irc, the bot is supposed to send hello world. But it only sends hello.
import socket
channel = "#bots"
server = "chat.freenode.org"
nickname = "my_bot"
class IRC:
irc = socket.socket()
def __init__(self):
self.irc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def send(self, chan, msg):
self.irc.send("PRIVMSG " + chan + " " + msg + "\n")
def connect(self, server, channel, botnick):
# defines the socket
print("connecting to: " + server)
self.irc.connect((server, 6667)) # connects to the server
self.irc.send("NICK %s\n" % botnick)
self.irc.send("USER %s %s Ibot :%s\n" % (botnick, botnick, botnick))
self.irc.send("JOIN %s\n" % channel)
self.irc.send("PRIVMSG %s :Hello Master\n" % channel)
def get_text(self):
text = self.irc.recv(2040) # receive the text
if text.find('PING') != -1:
self.irc.send('PONG ' + text.split()[1] + 'rn')
return text
irc = IRC()
irc.connect(server, channel, nickname)
while True:
text = irc.get_text().strip()
if "hello" in text.lower():
irc.send(channel, "hello world")
print text
You forgot a : before the message. This should work:
def send(self, chan, msg):
self.irc.send("PRIVMSG " + chan + " :" + msg + "\n")
Okay, so I've got a bit of Python IRC Bot code, and I recently added a weather command to it, but it doesn't seem to work... heres the code
# Import some necessary libraries.
import socket
import time
import httplib
def commands(nick,channel,message):
if message.find('!test')!=-1:
ircsock.send('PRIVMSG %s :%s: test complete\r\n' % (channel,nick))
elif message.find('!help')!=-1:
ircsock.send('PRIVMSG %s :%s: My other command is test.\r\n' % (channel,nick))
elif message.find('!sex')!=-1:
ircsock.send('PRIVMSG %s :%s: But why?\r\n' % (channel,nick))
elif message.find('!quit')!=-1:
ircsock.send('QUIT :For the bones of the weak shall support me\r\n')
die('Quit command given')
elif message.find('!op')!=-1:
ircsock.send('MODE %s +o :%s\n' % (channel,nick))
elif message.find('!deop')!=-1:
ircsock.send('MODE %s -o :%s\n' % (channel,nick))
elif message.find('!weather')!=-1:
tmp = message.find(':!weather')
city = tmp[1].strip()
reqest_str = '/laika_zinas/?city=' + city
c = httplib.HTTPConnection("www.1188.lv")
c.request("GET", reqest_str)
ra = c.getresponse()
datas = ra.read()
temp, wind = tpars(datas)
ircsock.send('PRIVMSG %s :%s: [+] Temp: '+ temp +' C | Wind: '+ wind +' m/s' % (channel,nick))
c.close()
# Some basic variables used to configure the bot
server = "n0cht.bawx.net" # Server
channel = "#python" # Channel
botnick = "PyleDrivr" # Your bots nick
def ping(ircmsg): # This is our first function! It will respond to server Pings.
ircsock.send("PONG "+ ircmsg +"\n")
print("Ping replied\n\r")
def sendmsg(chan , msg): # This is the send message function, it simply sends messages to the channel.
ircsock.send("PRIVMSG "+ chan +" :"+ msg +"\n")
def joinchan(chan): # This function is used to join channels.
ircsock.send("JOIN "+ chan +"\n")
ircsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ircsock.connect((server, 6667)) # Here we connect to the server using the port 6667
ircsock.send("USER "+ botnick +" "+ botnick +" "+ botnick +" :PyleDrivr\n") # user authentication
ircsock.send("NICK "+ botnick +"\n") # here we actually assign the nick to the bot
joinchan(channel) # Join the channel using the functions we previously defined
while 1: # Be careful with these! it might send you to an infinite loop
ircmsg = ircsock.recv(2048) # receive data from the server
ircmsg = ircmsg.strip('\n\r') # removing any unnecessary linebreaks.
print(ircmsg) # Here we print what's coming from the server
if ircmsg.find(' PRIVMSG ')!=-1:
nick=ircmsg.split('!')[0][1:]
channel=ircmsg.split(' PRIVMSG ')[-1].split(' :')[0]
commands(nick,channel,ircmsg)
if ircmsg.find("PING :") != -1: # if the server pings us then we've got to respond!
ping(ircmsg)
Now, when I run the bot, it works just fine, but then this happens when I issue the command:
<wh0r3[mint]> !weather 99654
* PyleDrivr has quit (Client exited)
And here's what the term shows:
:wh0r3[mint]!~wh0r3#n0cht-D1D272D.gci.net PRIVMSG #lobby :!weather 99654
Traceback (most recent call last):
File "pyledrivr.py", line 65, in <module>
commands(nick,channel,ircmsg)
File "pyledrivr.py", line 22, in commands
city = tmp[1].strip()
TypeError: 'int' object has no attribute '__getitem__'
I have no idea what this means or how to fix it. and ideas?
This line:
tmp = message.find(':!weather')
assigns an integer to tmp: the position at which the string ':!weather' was found in message (see find). It may not even be found at all, since you check in the line above that '!weather' is in message, not ':!weather'.
Then you try and access tmp[1]. But tmp is just a number; it doesn't have a [1].
If you want to get the substring of message that follows '!weather', you could do this:
city = message[message.find('!weather')+8:].strip()
(8 being the length of '!weather')
Or you might find it easier to use split:
city = message.split('!weather')[1].strip()
So I am just getting into python and trying out some stuff. To start, I am making a server that does simple stuff like "GET"s stored text, "STORE"s new text over the old stored text, and "TRANSLATE"s lowercase text into uppercase. But I have a few questions. Here is my code so far:
import socket
HOST = '' # Symbolic name meaning the local host
PORT = 24069 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
try:
s.bind((HOST, PORT))
except socket.error , msg:
print 'Bind failed. Error code: ' + str(msg[0]) + 'Error message: ' + msg[1]
sys.exit()
print 'Socket bind complete'
s.listen(1)
print 'Socket now listening'
while 1:
conn, addr = s.accept()
print 'Connected with ' + addr[0] + ':' + str(addr[1])
data = conn.recv(1024)
reply = 'OK...' + data
if not data: break
conn.send(data)
conn.close()
s.close()
To start changing text from a client into uppercase, from my other programming knowledge, I assume I'd store the client's text in a variable and then run a function on it to change it to uppercase. Is there such a function in python? Could someone please give me a snippet of how this would look?
And lastly, how would I do something like a GET or STORE in python? My best guess would be:
data = conn.recv(1024)
if data == GET: print text
if data == STORE: text = data #Not sure how to reference the text that the client has entered
Thank you so much for any help! :)
Note to self:
import socket
HOST = '' # Symbolic name meaning the local host
PORT = 24069 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
try:
s.bind((HOST, PORT))
except socket.error , msg:
print 'Bind failed. Error code: ' + str(msg[0]) + 'Error message: ' + msg[1]
sys.exit()
print 'Socket bind complete'
s.listen(1)
print 'Socket now listening'
# Accept the connection
(conn, addr) = s.accept()
print 'Server: got connection from client ' + addr[0] + ':' + str(addr[1])
storedText = 'Hiya!'
while 1:
data = conn.recv(1024)
tokens = data.split(' ', 1)
command = tokens[0]
if command == 'GET':
print addr[0] + ':' + str(addr[1]) + ' sends GET'
reply = storedText
elif command == 'STORE':
print addr[0] + ':' + str(addr[1]) + ' sends STORE'
storedText = tokens[0]
reply = '200 OK\n' + storedText
elif command == 'TRANSLATE':
print addr[0] + ':' + str(addr[1]) + ' sends TRANSLATE'
storedText = storedText.upper()
reply = storedText
elif command == 'EXIT':
print addr[0] + ':' + str(addr[1]) + ' sends EXIT'
conn.send('200 OK')
break
else:
reply = '400 Command not valid.'
# Send reply
conn.send(reply)
conn.close()
s.close()
I see that you're quite new to Python. You can try to find some code example, and you should also learn how to interpret the error message. The error message will give you the line number where you should look at. You should consider that line or previous line, as the error may be caused by previous mistakes.
Anyway, after your edits, do you still have indentation error?
On your real question, first, the concept.
To run client/server, you'll need two scripts: one as the client and one as the server.
On the server, the script will just need to bind to a socket and listen to that connection, receive data, process the data and then return the result. This is what you've done correctly, except that you just need to process the data before sending response.
For starter, you don't need to include the accept in the while loop, just accept one connection, then stay with it until client closes.
So you might do something like this in the server:
# Accept the connection once (for starter)
(conn, addr) = s.accept()
print 'Connected with ' + addr[0] + ':' + str(addr[1])
stored_data = ''
while True:
# RECEIVE DATA
data = conn.recv(1024)
# PROCESS DATA
tokens = data.split(' ',1) # Split by space at most once
command = tokens[0] # The first token is the command
if command=='GET': # The client requests the data
reply = stored_data # Return the stored data
elif command=='STORE': # The client want to store data
stored_data = tokens[1] # Get the data as second token, save it
reply = 'OK' # Acknowledge that we have stored the data
elif command=='TRANSLATE': # Client wants to translate
stored_data = stored_data.upper() # Convert to upper case
reply = stored_data # Reply with the converted data
elif command=='QUIT': # Client is done
conn.send('Quit') # Acknowledge
break # Quit the loop
else:
reply = 'Unknown command'
# SEND REPLY
conn.send(reply)
conn.close() # When we are out of the loop, we're done, close
and in the client:
import socket
HOST = '' # Symbolic name meaning the local host
PORT = 24069 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST,PORT))
while True:
command = raw_input('Enter your command: ')
if command.split(' ',1)[0]=='STORE':
while True:
additional_text = raw_input()
command = command+'\n'+additional_text
if additional_text=='.':
break
s.send(command)
reply = s.recv(1024)
if reply=='Quit':
break
print reply
Sample run (first run the server, then run the client) on client console:
Enter your command: STORE this is a text
OK
Enter your command: GET
this is a text
Enter your command: TRANSLATE
THIS IS A TEXT
Enter your command: GET
THIS IS A TEXT
Enter your command: QUIT
I hope you can continue from there.
Another important point is that, you're using TCP (socket.SOCK_STREAM), so you can actually retain the connection after accepting it with s.accept(), and you should only close it when you have accomplished the task on that connection (accepting new connection has its overhead). Your current code will only be able to handle single client. But, I think for starter, this is good enough. After you've confident with this, you can try to handle more clients by using threading.