I made a basic IRC bot that would join a certain channel and say a defined phrase, as part of learning Python. However, are there changes in the latest version of Python?
import socket
nick = 'TigerBot'
passdwd = '*****'
port = '6667'
net = 'irc.snoonet.org'
chan = '#WritingPrompts'
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Was ist da IRC Socket?
sock.connect ((net, port)) # Open server connection
irc.recv (4096) # Buffer setup
irc.send('nick ' + nick + '\r\n') # What is your name?
irc.send('USER AffixBot AffixBot AffixBot :Affix IRC\r\n') #Send User Info to the server
irc.send('JOIN ' + chan + '\r\n') # Join the pre defined channel
irc.send('PRIVMSG ' + chan + ' :Hello.\r\n') #Send a Message to the channel
while True: #While Connection is Active
data = irc.recv (4096) #Make Data the Receive Buffer
if data.find('PING') != -1: # If PING
irc.send('PONG ' + data.split()[1] + '\r\n') # Then PONG
Line 11 is the problem - apparently, what I've got down as a string needs to be an integer. How can I go about this?
Change your definition of port to be an integer.
port = 6667
not
port = '6667'
In general, if you have an existing string value that needs to be an int for a specific call, you can cast by calling int(str), which will return the value of str as an integer or raise a ValueError if it can't cast.
Related
I am coding an assignment and got the code to successfully send an email to my email address. How can I correctly use a loop to ask the user if they want to send another email or quit. You can see how I attempted this but it doesn't seem to work. Additionally, How do I make it ask them to log into their outlook account and/or ask them the email address of the recipient?
Many thanks for taking time to read
This is the code:
from socket import *
import ssl
import base64
# Some global variables
SMTP_MAIL_SERVER = 'smtp-mail.outlook.com'
SMTP_TLS_PORT = 587
END_MESSAGE = '\r\n.\r\n'
client_socket = None
ssl_context = None
def send_line(line):
global client_socket
print('CLIENT: ' + line.strip())
client_socket.send(line.encode())
response = client_socket.recv(1024).decode()
return response
def get_code(response):
return int(response[:3])
def connect():
global client_socket
global ssl_context
print('CLIENT: Connecting to ' + SMTP_MAIL_SERVER)
client_socket = socket(AF_INET, SOCK_STREAM)
client_socket.connect((SMTP_MAIL_SERVER, SMTP_TLS_PORT))
response = client_socket.recv(1024).decode()
return response
def send_ehlo():
helo = 'ehlo smtp-mail.outlook.com\r\n'
return send_line(helo)
def send_helo():
helo = 'helo smtp-mail.outlook.com\r\n'
return send_line(helo)
def start_tls():
global client_socket
global ssl_context
response = send_line('STARTTLS \r\n')
ssl_context = ssl._create_stdlib_context()
client_socket = ssl_context.wrap_socket(client_socket, server_hostname=SMTP_MAIL_SERVER)
return response
def send_auth_request():
return send_line('auth login \r\n')
def send_username(username):
as_bytes = username.encode('ascii')
as_b64 = base64.b64encode(as_bytes)
as_utf8 = as_b64.decode('utf-8')
return send_line(as_utf8 + '\r\n')
def send_password(password):
as_bytes = password.encode('ascii')
as_b64 = base64.b64encode(as_bytes)
as_utf8 = as_b64.decode('utf-8')
return send_line(as_utf8 + '\r\n')
'''--------------------------------------------------------------------------------
TODO - Implement the functions below this point in order to send a test
email successfully using SMTP commands
--------------------------------------------------------------------------------'''
def send_mail_from(sender):
mail_from = 'MAIL FROM: <' + sender + '>\r\n'
return send_line(mail_from)
def send_rcpt_to(recipient):
rcpt_to = 'RCPT TO: <' + recipient + '>\r\n'
return send_line(rcpt_to)
def send_begin_data():
return send_line('DATA \r\n')
def send_message(subject, message):
subject_line = 'Subject: ' + subject + '\r\n'
body = '\nMessage:' + message + '\r\n'
return send_line(subject_line + body + END_MESSAGE)
def send_quit():
return send_line('QUIT \r\n')
'''--------------------------------------------------------------------------------
TODO - Implement the functions above this point in order to send a test
email successfully using SMTP commands
--------------------------------------------------------------------------------'''
send_email_question = 1
while send_email_question == 1:
def send_one_email():
# Open a TCP connection - the reply should start '220'
reply = connect()
print('SERVER: ' + reply)
# Send a EHLO command - the reply should be a list of supported
# 'enhanced' SMTP functions each starting '250'
reply = send_ehlo()
print('SERVER: ' + reply)
# Ask the server to switch to TLS - reply should start '220'
reply = start_tls()
print('SERVER: ' + reply)
# Send a HELO command encrypted - reply should start '220'
reply = send_helo()
print('SERVER: ' + reply)
# Send an AUTH LOGIN command
reply = send_auth_request()
print('SERVER: ' + reply)
# Send your (base64 encoded username) -
reply = send_username('#sending email username')
print('SERVER: ' + reply)
# Send your (base64 encoded username) -
reply = send_password('#sending email password')
print('SERVER: ' + reply)
# Send MAILFROM command - TODO - YOU IMPLEMENT THE FUNCTION BELOW
reply = send_mail_from('#sending email') #sending email
print('SERVER: ' + reply)
# Send RCPT TO command - TODO - YOU IMPLEMENT THE FUNCTION BELOW
reply=send_rcpt_to('#target email') #target email
print('SERVER: ' + reply)
# Send DATA command - TODO - YOU IMPLEMENT THE FUNCTION BELOW
reply = send_begin_data()
print('SERVER: ' + reply)
# Send the message (including subject) - TODO - YOU IMPLEMENT THE FUNCTION BELOW
reply = send_message(subject='Nothing much', message='Hello World')
print('SERVER: ' + reply)
# Quit the SMTP session - TODO - YOU IMPLEMENT THE FUNCTION BELOW
user_end_question = int(input("Please enter 1 if you would like to send another email 0 to end connection: "))
if user_end_question == 0:
reply = send_quit()
print('SERVER: ' + reply)
if __name__ == '__main__':
send_one_email()
When doing :
send_email_question = 1
while send_email_question == 1:
def send_one_email():
# ... [snip lots of send/reply]
user_end_question = int(input("Please enter 1 if you would like to send another email 0 to end connection: "))
if user_end_question == 0:
reply = send_quit()
print('SERVER: ' + reply)
if __name__ == '__main__':
send_one_email()
you are entering the loop, which creates a function (one def instruction). Then in the if __name__ you call one time the function which was created.
Instead, you should do :
def send_one_email():
# ... [snip lots of send/reply]
if __name__ == '__main__':
send_email_question = 1
while send_email_question == 1:
send_one_email()
user_end_question = int(input("Please enter 1 if you would like to send another email 0 to end connection: "))
if user_end_question == 0:
reply = send_quit()
print('SERVER: ' + reply)
which is creating the function (only once), then in a loop sending an email and asking whether to quit. This way, the send_one_email just sends one email, and do nothing else. And your "main" part decides how many times to call it.
99% of the time, you don't want to create functions (def) inside loops.
I have been looking for a solution for this problem since days but wasn't able to find any, I'm interested in knowing which ports are closed (ie there is host that returned that this port is closed) and which are timed out.
My current code:
ssdpDiscover = (
'M-SEARCH * HTTP/1.1\r\n' + 'HOST: ' + ip + ':1900\r\n' + 'MAN: "ssdp:discover"\r\n' + 'MX: 1\r\n' + 'ST: ssdp:all\r\n' + '\r\n')
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
sock.sendto(ssdpDiscover.encode('ASCII'), (ip, UPnP_PORT))
sock.settimeout(3) #seconds
while 1:
data, address = sock.recvfrom(BUFFER_SIZE)
upnp_obj['state'] = 'open'
location_result = location_regex.search(data.decode('ASCII'))
if location_result:
location = location_result.group(1)
break
except socket.timeout:
upnp_obj['state'] = 'timeout'
How can I detect if the host sent back a message telling if port is closed or not?
I copied an already made irc script and modified it a bit.
# Import some necessary libraries.
import socket
channelList = []
# Some basic variables used to configure the bot
server = "irc.freenode.net" # Server
channel = "#kiwiirc-default" # Channel
botnick = "Mybot" # Your bots nick
def ping(): # This is our first function! It will respond to server Pings.
ircsock.send("PONG :pingis\n")
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 +" :This bot is a result of a tutoral covered on http://shellium.org/wiki.\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
send = True
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 send:
ircsock.send('LIST\r\n')
send = False
x = ircmsg.split()
x = [val for i, val in enumerate(x) if '#' in val]
channelList += x
print len(channelList)
if 'PING :' in ircmsg: # if the server pings us then we've got to respond!
ping()
raw_input()
It sends the LIST to the server and the server will send back the information. I then add it to a channelList and print out the length.
When I type /list into my irc client, it returns "49400 channels found"
The final channelList length should be 49400, but it is always 18,000ish (forgot the exact number)
I'm using https://kiwiirc.com/client
I'm currently trying to write process that embeds a sequence of n IPs into packets and send it off to n server. Each server remove the outermost IP and then forward it to said IP. This is exactly like tunneling I know. During the process I also want the server to do a traceroute to where it's forwarding the packet and send that back to the previous server.
My code currently will forward the packets but it's stuck on performing the traceroute and getting it. I believe it's currently stuck in the while loop in the intermediate server. I think it's having something to do with me not closing the sockets properly. Any suggestion?
Client
#!/usr/bin/env python
import socket # Import socket module
import sys
import os
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
port = 17353 # Reserve a port
FILE = raw_input("Enter filename: \n ")
NIP = raw_input("Enter Number of IPs: ")
accepted_IP = 0
IP= []
while accepted_IP < int(NIP):
IP.append(raw_input("Enter destination IP: \n"))
accepted_IP +=1
#cIP = raw_input("Enter intemediate IP: \n ")
ipv = raw_input("Enter IP version... 4/6")
try:
s.connect((host, port))
print "Connection sucessful!"
except socket.error as err:
print "Connection failed. Error: %s" %err
quit()
raw = open(FILE,"rb")
size = os.stat(FILE).st_size
ls = ""
buf = 0
for i in IP:
while len(i) < 15:
i += "$"
ls += i
header = ipv+NIP+ls+FILE
print ls
s.sendall(header + "\n")
print "Sent header"
data = raw.read(56) +ipv + NIP + ls
print "Begin sending file"
while buf <= size:
s.send(data)
print data
buf += 56
data = raw.read(56) + ipv + NIP + ls
raw.close()
print "Begin receiving traceroute"
with open("trace_log.txt","w") as tracert:
trace = s.recv(1024)
while trace:
treacert.write(trace)
if not trace: break
trace = s.recv(1024)
print "finished forwarding"
s.close()
Intermediate server
#!/usr/bin/env python
import socket
import subprocess
srvsock = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
srvsock.bind( (socket.gethostname(), 17353) )
srvsock.listen( 5 ) # Begin listening with backlog of 5
# Run server
while True:
clisock, (remhost, remport) = srvsock.accept() #Accept connection
print
d = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
header = ""
while True:
b = clisock.recv(1)
if b == "\n":
break
header += b
num = 15 * int(header[1]) + 2
file_name = header[num:]
nheader = header[0]+ str(int(header[1])-1) + header[17:]
d.connect((socket.gethostname(), 12355))
d.sendall(nheader+'\n')
print "begin forwarding"
while True:
raw = clisock.recv(56 + num) # recieve data
ip = raw[-15:] # extract IP
ipv, NIP = raw[57] , str(int(raw[57])-1)
if NIP == "0":
while (raw):
print "stuck in this loop"
d.send(raw[:56])
raw=clisock.recv(56+num)
if not raw: break
else:
while (raw):
print raw[:57] + NIP + raw[59:-15]
print "\n"
d.send(raw[:57] + NIP + raw[59:-15])
raw = clisock.recv(56+num)
if not raw :break
print "Finish forwarding"
d.close()
break
print "Begin traceroute"
tracrt = subprocess.Popen(['traceroute','google.com'], stdout=subprocess.PIPE)
s.sendall(tracrt.communicate()[0])
print "Finished"
clisock.close()
s.close()
Destination server
import socket
s = socket.socket()
host = socket.gethostname()
port = 12355
s.bind((host,port))
s.listen(5)
while True:
csock, (client, cport) = s.accept()
print client
header = ""
while True:
b = csock.recv(1)
if b == "\n":
break
header += b
file_name = header[2:]
r = open("File_test_"+file_name,"wb")
print 'Opening file for writing'
while True:
print "Begin writing file" + " " + file_name
raw = csock.recv(56)
while (raw):
print raw
r.write(raw)
raw = csock.recv(56)
r.flush()
r.close()
print "finish writing"
break
print "closing connection"
csock.close()
s.close()
The intermediate server is stuck in clisock.recv() in this loop because the break condition not raw isn't met before the connection is closed by the client, and the client doesn't close the connection before receiving the traceroute from the intermediate server, so they are waiting on each other.
To remedy this, you might consider sending the file size to the intermediate server, so that it can be used to determine when the receive loop is done. Or, if your platform supports shutting down one half of the connection, you can use
s.shutdown(socket.SHUT_WR)
in the client after sending the file.
I'm making a UDP program that connects multiple clients/neighbors. There is no server everyone is using the same program. I'm trying to test it with localhost so consider all IPs and ports of neighbors work as intended. Using 127.0.0.1 as IP on all and connecting to different ports.
So my question is why do I receive the startup data that I send before the while loop but I cannot send any? Seems that I am doing something wrong with sys.stdin.
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((HOST, PORT))
going = True
input = [s]
while going:
i,o,e = select.select(input,[],[],)
try :
for x in i:
if x == sys.stdin:
data = sys.stdin.read()
for i in neighbors:
addr = (i[1][0], int(i[1][1]))
s.sendto(data, addr)
else:
msg, addr = s.recvfrom(100)
print msg
except socket.error, msg:
print 'Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
s.close()
input is always [s], so i is always going to be [s], so x == sys.stdin is never going to be True (because x is always s), so only the else clause will ever execute.
Maybe you meant input = [s, sys.stdin]?