import os.path
import re
import socket
host = ''
port = 6366
s = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
s.bind ((host, port))
def request ():
print ("What file should I write to?")
file = input ()
thing = os.path.exists (file)
if thing == True:
start = 0
elif file.endswith ('.txt'):
stuff = open (file, "w")
stuff.write ("Requests on what to add to the server. \n")
stuff.close ()
start = 0
else:
start = 1
go = "yes"
list1 = (start, file, go)
return list1
start = 1
while start == 1:
list1 = request ()
(start, file, go) = list1
def loop ():
print ("Listening for requests.")
s.listen (1)
conn, addr = s.accept ()
print ("Connected to {0}".format(addr))
while 1:
want = conn.recv(1024).decode()
if not want:
break
if want == "shutdown":
thingy = "no"
print ("Writing to {0}".format(file))
x = open (file, "a")
x.write (want + "\n")
x.close ()
print ("Done writing to {0}".format(file))
x = open (file, "a")
x.write (format(addr) + "\n")
x.close ()
print ("Disconnecting from {0}".format(addr))
conn.close()
print ("Disconnected from {0}".format(addr))
return thingy
while go == "yes":
go = loop ()
if go == "no":
print ("Shutting down")
This is a server. Whenever I try and return "thingy" on line 50, I get the following error.
Traceback (most recent call last):
File "H:\Python\Server Requests\Listen.py", line 52, in <module>
go = loop ()
File "H:\Python\Server Requests\Listen.py", line 50, in loop
return thingy
UnboundLocalError: local variable 'thingy' referenced before assignment
I don't understand why I'm getting this error. I haven't referenced it outside of that one loop. Is there something I'm missing?
For that error;
def loop ():
print ("Listening for requests.")
thingy=""
s.listen (1)
conn, addr = s.accept ()
print ("Connected to {0}".format(addr))
Just add an empty variable called thingy in function. It should solve your problem.
Try Declaring an Empty Variable and then assign values if it satisfy condition. Your return statement will work.
Related
This is the code for p2p based on sockets that I am working on.
Whenever I try to execute this I get global name not defined error.
import socket
import os.path
import sys
import urlparse
import threading
class Node:
def startlisten(sock):
sock.listen(6)
while True:
c,addr = sock.accept()
print "Client connected all set to go : "+str(addr)
thread1 = threading(target=retrfile,args=(c,))
thread1.start()
def __init__(self):
self.port=raw_input("Enter the port: ")
self.shareddir=raw_input("Enter the name of the folder you want to share: ")
self.sysname=raw_input("Enter your desired nick name: ")
self.known=set()
self.s=socket.socket()
host = socket.gethostname()
port = int(self.port)
print host,port
self.s.bind((host,port))
t=threading.Thread(target=startlisten,args =(self.s,))
t.start()
def retrfile(sock):
code,filename = sock.recv(1024)
if code == 0:
if os.pathisfile(os.path.join("D:\\Sankalp0203\\",filename)):
sock.send("OK",str(os.path.getsize(filename)))
userResponse = sock.recv(1024)
if userResponse == 'Y':
with open(filename,'rb') as f:
bytestoread = f.read(1024)
sock.send(1024)
while bytestoread != "":
bytestoread = f.read(1024)
sock.send(byestoread)
def _hello(self,other):
self.known.add(other)
def _broadcast(self,query,history):
for other in self.known.copy():
if other in history:
continue
try:
name = urlparse(other)[1]
parts=name.split(":")
port = int(parts[-1])
host = "http://"+parts[0]
self.s.connect((host,port))
self.s.send(0,query)
code , size = s.recv(1024)
if code == "OK":
inp = raw_input("File Exists and filesize : "+str(size)+" download? y/n: ")
if inp == Y:
self.s.send(Y)
write(self.s,size)
return code , size,
except:
self.known.remove(other)
return FAIL,EMPTY
def write(sock1,size):
f = open('new'+filename,'wb')
data = sock1.recv(1024)
totalrecv = len(data)
f.write(data)
while(totalrecv < size):
data = sock1.recv(1024)
f.write(data)
totalrecv+=len(data)
def Main():
n=Node()
num=3
while(num):
input = (int)(raw_input("Enter 1 for fetch and 2 to sit idle and 3 to introduce to new peer"))
if(input == 1):
filename = raw_input("Enter the name of the file")
n.query(filename)
if(input == 3):
frnd =raw_input("Enter the url of the friend socket")
n._hello(frnd)
if __name__=='__main__':
Main()
When I execute this i get the following error saying global name not defined pls help
Traceback (most recent call last):
File "D:/Sankalp0203/P2Per.py", line 101, in <module>
Main()
File "D:/Sankalp0203/P2Per.py", line 89, in Main
n=Node()
File "D:/Sankalp0203/P2Per.py", line 28, in __init__
t=threading.Thread(target=startlisten,args =(self.s,))
NameError: global name 'startlisten' is not defined
It's saying that startlisten is not defined because global name startlisten is not defined. There is no global function called startlisten. The method you created is under the Node class. You missed the self. The right way to do it would be:
t=threading.Thread(target=self.startlisten,args =(self.s,))
I'm writing a socket communication program, I have a main thread, and another thread trying to sock.recv()
when it does recieve bytes, it works as it needs, it goes to the right function, which at the end prints, and then the thread listens again to bytes (as wanted).
the problem is that the program won't print until I press enter...
if it matters i'm getting input at the same time in the main thread but it shouldn't matter.
note - the bytes are sent like this:
int (4 bytes) - msg type (string to print is 2)
int (4 bytes) - length of text to print
string ( bytes) - actual text
full code:
import socket
import time
import struct
import threading
import sys
PORT = 54321
def try_to_connect(ip):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
socket.IPPROTO_TCP)
sock.settimeout(1)
try:
sock.connect((ip, PORT))
return sock
except:
return False
def text_parse(text, msg_id):
byte_text = bytes(text, "utf-8")
return struct.pack("II%ds" % len(byte_text), msg_id, len(byte_text), byte_text)
def main(sock):
global file_name
print("connected succefuly. to run a command, write $<command> (no space)\nto request a file, enter file path.\nto exit this program enter exit.")
inputed_text = ''
while True:
inputed_text = input()
if inputed_text == '':
pass
elif inputed_text == "exit":
return
elif inputed_text[0] == "$":
sock.send(text_parse(inputed_text[1:], 0))
else:
file_name = inputed_text
sock.send(text_parse(inputed_text, 1))
def print_string(message, msg_len):
text = struct.unpack("%ds" % msg_len, message)[0].decode("utf-8")
sys.stdout.write(text)
sys.stdout.flush()
def copy_file(message):
global file_name
final_file = open(file_name, "wb")
final_file.write(message)
final_file.close()
def recieve_loop(sock):
while True:
try:
header = sock.recv(8)
if not header: break
msg_type = struct.unpack("I", header[:4])[0]
msg_len = struct.unpack("I", header[4:8])[0]
print(msg_type)
print(msg_len)
message = sock.recv(msg_len)
if msg_type == 2:
print_string(message, msg_len)
elif msg_type == 3:
copy_file(message)
except socket.timeout:
pass
if __name__ == "__main__":
print("welcome to remote desktop program.\nto connect to your computer, enter it's ip.\nto exit enter exit")
text_input = "b,kjhkf"
while True:
text_input = input()
if text_input == "exit":
exit()
else:
sock = try_to_connect(text_input)
if sock:
socket_recieve_thread = threading.Thread(target = recieve_loop, args = [sock])
socket_recieve_thread.start()
main(sock)
socket_recieve_thread.join()
else:
print("the computer is not online")
I have this script that allow the user to enter the file name by an argument and then it updates the file version:
#!/usr/bin/env python
import os
import sys
class versionBumper:
def __init__(self):
self.version = None
self.SavedBefore = ""
self.SavedAfter = ""
def change_version(self, file_to_be_modded, packageVersion):
for line in file_to_be_modded:
if packageVersion in line:
print "VERSION FOUND: ", line
self.VersionNumber = line
elif self.VersionNumber is None:
self.SavedBefore += line
else:
self.SavedAfter += line
file_to_be_modded.close()
print "Version: ", self.VersionNumber
return self.VersionNumber
if __name__ == '__main__':
print "sys.argv[1:]:", sys.argv[0:]
versionBumper123 = versionBumper()
filename = sys.argv[1]
path = "/home/Desktop/Crate/Crate/" + filename + "/build/CMakeLists.txt"
if os.path.exists:
inputFile = open(path, 'r')
else:
print "no match found"
sys.exit()
print "Which version number to bump ?"
print "1) major"
print "2) minor."
print "3) patch."
Choose_version = raw_input("Choose version: ")
if Choose_version == "1":
version = versionBumper123.change_version(inputFile, "_MAJOR ")
elif Choose_version == "2":
version = versionBumper123.change_version(inputFile, "_MINOR ")
elif Choose_version == "3":
version = versionBumper123.change_version(inputFile, "_PATCH ")
else:
print "Invalid input. Exiting gracefully..."
sys.exit()
outputFile = open (path, 'w')
splitted_version_line_substrings = version.split('"')
Version_Name = splitted_version_line_substrings[0]
Version_Number = int(splitted_version_line_substrings[1]) + 1
parenthesis = splitted_version_line_substrings[2]
new_version = (str(Version_Name) + '"'
+ str(Version_Number) + '"'
+ str(parenthesis))
print "new_version: ", new_version
outputFile.write(str(versionBumper123.SavedBefore))
outputFile.write(str(new_version))
outputFile.write(str(versionBumper123.SavedAfter))
But I keep getting this error:
Traceback (most recent call last):
File "untitled.py", line 57, in <module>
splitted_version_line_substrings = version.split('"')
NameError: name 'version' is not defined.
I also tried to define version as a global variable but that also did not work, I can't really figure out how to call version from outside the function it is defined in.
Me thinks that you are dealing with a single instance of your class versionBumper
versionBumper123 = versionBumper()
so I guess that what you want to do with the statement
splitted_version_line_substrings = version.split('"')
should be expressed as
splitted_version_line_substrings = versionBumper123.version.split('"')
Just because you use a single instance of your class, imho you could write simpler code if you don't use a class.
import os.path
import re
def request ():
print ("What file should I write to?")
file = input ()
thing = os.path.exists (file)
if thing == "true":
start = 0
elif re.match ("^.+.\txt$", file):
stuff = open (file, "w")
stuff.write ("Requests on what to add to the server.")
stuff.close ()
start = 0
else:
start = 1
go = "yes"
list1 = (start, file, go)
return list1
start = 1
while start == 1:
request ()
(start, file, go) = list1
I try to return get list1 to return and unpack it in the loop so I can set variables that come after the while loop. Whenever I try and run this and enter "Thing.txt", I get NameError: name 'list1' is not defined. Am I missing something here?
Try this:
# -*- coding: utf-8 -*-
#!/usr/bin/python
import os.path
import re
def request ():
print ("What file should I write to?")
file = input ()
thing = os.path.exists (file)
# thing is a boolean variable but not a string, no need to use '=='
if thing:
start = 0
elif re.match ("^.+.\txt$", file):
stuff = open (file, "w")
stuff.write ("Requests on what to add to the server.")
stuff.close ()
start = 0
else:
start = 1
go = "yes"
list1 = (start, file, go)
return list1
start = 1
while start == 1:
# you need to get return value of function request
list1 = request ()
(start, file, go) = list1
# Or you can simply write this way (start, file, go) = request()
I am working on a Python chat script, the client looks like this:
import sys
import util
import thread
import socket
class ClientSocket():
rbufsize = -1
wbufsize = 0
def __init__(self, address, nickname=''):
if type(address) == type(()) and type(address[0]) == type('') and
type(address[1])== type(1):
pass
else:
print ('Address is of incorrect type. \n' +
'Must be (serverHost (str), serverPort (int)).')
sys.exit(1)
if nickname:
self.changeNick(nickname)
else:
self.changeNick(raw_input('Nickname: '))
self.prompt_on = False
self.address = address
def connect(self):
self.connection=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.connection.connect(self.address)
self.rfile = self.connection.makefile('rb', self.rbufsize)
self.wfile = self.connection.makefile('wb', self.wbufsize)
self.wfile.write('/nick ' + self.nickname + '\n')
def serve_forever(self):
self.connect()
thread.start_new_thread(self.acceptinput,())
line = ""
while line not in ('/exit','/quit', '/q'):
self.prompt_on = True
line = raw_input(self.prompt)
self.prompt_on = False
if line[:2] == '/n' or line[:5] == '/nick':
self.changeNick(line.split(' ', 1)[1].strip())
self.wfile.write(line + '\n')
self.close()
self.connection.shutdown(socket.SHUT_RDWR)
self.connection.close()
def changeNick(self, newNick):
self.nickname = newNick
self.prompt = self.nickname+': '
self.backspace = '\b' * len(self.prompt)
def acceptinput(self):
while 1:
data = self.rfile.readline().strip()
if data:
self.writedata(data)
if 'Nickname successfully changed to' in data:
self.changeNick(data.split('"')[1])
def writedata(self, data):
if self.prompt_on:
output = data if len(data) >= len(self.prompt) else data + ' '
(len(self.prompt) - len(data))
sys.stdout.write(self.backspace + output + '\n' + self.prompt)
sys.stdout.flush()
else:
print data
def close(self):
if not self.wfile.closed:
self.wfile.flush()
self.wfile.close()
self.rfile.close()
def main():
serverHost = raw_input('Server IP/Hostname: ')
if not serverHost:
serverHost = util.getIP()
else:
serverHost = socket.gethostbyname(serverHost)
serverPort = input('Server Port: ')
address = (serverHost, serverPort)
client = ClientSocket(address)
print 'Connecting to server on %s:%s' % (serverHost, serverPort)
client.serve_forever()
if __name__ == '__main__':
main()
I was wondering if there would be a way to play a sound every time a new messages. Possible using winsound ? (http://stackoverflow.com/questions/307305/play-a-sound-with-python)
Thanks:)
I am pleasantly surprised that winsound is standard library module. Just note that is only available on Windows.
What happens in your writa_data function you do this after the flush. Does this get your desired effect?
import winsound
# Play Windows exit sound.
winsound.PlaySound("SystemExit", winsound.SND_ALIAS)
Okay, figured it out !!! Thanks for the help! :DDD
You add the winsound.PlaySound("SystemExit", winsound.SND_ALIAS) on line 101, above the sys.stdout.write(self.backspace + output + '\n' + self.prompt). Now whenever a new message comes through, it plays a 'ding!'. If you wanted to use a custom .wav sound from the same directory the script is running from, add a winsound.PlaySound("ding.wav", winsound.SND_FILENAME) on line #101 instead. Enjoy!