Unable to write to the client after downloading a file - python

I have been able to receive the file from the socket and download it, but when I try to push a message from the server to the client the message is never displayed on the client side.
Below is the code and any help would be highly appreciated as I am a novice to network programming.
# get the hostname
host = socket.gethostname()
port = 5000 # initiate port no above 1024
Buffer = 1024
server_socket = socket.socket() # get instance
# look closely. The bind() function takes tuple as argument
server_socket.bind((host, port)) # bind host address and port together
# configure how many client the server can listen simultaneously
server_socket.listen(2)
conn, address = server_socket.accept() # accept new connection
print("Connection from: " + str(address))
f = open("FileFromServer.txt", "wb")
# receive data stream. it won't accept data packet greater than 1024 bytes
data = conn.recv(Buffer)
while data:
f.write(data)
print("from connected user: " + str(data))
data = conn.recv(Buffer)
f.close()
print 'Data Recivede'
datas = 'Recived the file Thanks'
if datas is not '':
conn.send(datas) # send data to the client
conn.close() # close the connection
host = socket.gethostname() # as both code is running on same pc
port = 5000 # socket server port number
client_socket = socket.socket() # instantiate
client_socket.connect((host, port)) # connect to the server
with open('T.txt', 'rb') as f:
print 'file openedfor sending'
l = f.read(1024)
while True:
client_socket.send(l)
l = f.read(1024)
f.close()
print('Done sending')
print('receiving data...')
data = client_socket.recv(1024)
print data
client_socket.close() # close the connection
print 'conection closed

The thing is that you both you server and client socket stuck in the while loop:
try this client.py:
import socket
host = socket.gethostname() # as both code is running on same pc
port = 5000 # socket server port number
client_socket = socket.socket() # instantiate
client_socket.connect((host, port)) # connect to the server
end = '$END MARKER$'
with open('T.txt', 'rb') as f:
print('file opened for sending')
while True:
l = f.read(1024)
if len(l + end) < 1024:
client_socket.send(l+end)
break
client_socket.send(l)
print('Done sending')
print('receiving data...')
data = client_socket.recv(1024)
print(data)
client_socket.close() # close the connection
print('conection closed')
server.py
import socket
# get the hostname
host = socket.gethostname()
port = 5000 # initiate port no above 1024
Buffer = 1024
end = '$END MARKER$'
server_socket = socket.socket() # get instance
# look closely. The bind() function takes tuple as argument
server_socket.bind((host, port)) # bind host address and port together
# configure how many client the server can listen simultaneously
server_socket.listen(2)
conn, address = server_socket.accept() # accept new connection
print("Connection from: " + str(address))
# receive data stream. it won't accept data packet greater than 1024 bytes
with open("FileFromServer.txt", "ab") as f:
while True:
data = conn.recv(Buffer)
if end in data:
f.write(data[:data.find(end)])
conn.send(b'Recived the file Thanks')
break
f.write(data)
conn.close()

Related

Python socket programming: ConnectionRefusedError: [Errno 111] Connection refused

I am sending ssh count data from 'alphaclient' to 'alphaserver'. However the alphaclient server is not able to connect with alphaserver. Kindly help me resolve this error. I tried to kill the process at the port and restart the VMs but still getting the same issue.
This is the error output in alphaclient:
Traceback (most recent call last):
File "//./sshlogin-counter/alphaclient.py", line 82, in <module>
inform_alphaserver(client_message)
File "//./sshlogin-counter/alphaclient.py", line 45, in inform_alphaserver
c.connect((alphaserver_ip,port))
ConnectionRefusedError: [Errno 111] Connection refused
and this is the output in alphaserver:
Binding alphaserver at port 7888
Server Socket created.
Server socket binded at port 7888
Listening to port...
alphaclient.py
import os
import socket
input_file = os.path.join('/','var', 'log', 'auth.log')
#output_file = os.path.join('.','sshlogin-counter','client_message.txt')
total_ssh_attempts = 0
#Function1 that reads /var/log/auth.log and returns total ssh attempts made into that VM
def ssh_attempts(input_file):
successful_ssh_attempts = 0
invalid_ssh_attempts = 0
current_ssh_attempts = 0
with open(input_file,'r') as f:
f = f.readlines() #list of lines
for line in f:
if 'sshd' and 'Accepted publickey' in line:
successful_ssh_attempts+=1
#elif 'sshd' and 'Invalid user' in line:
#invalid_ssh_attempts+=1
current_ssh_attempts = successful_ssh_attempts + invalid_ssh_attempts
return (current_ssh_attempts)
#Function2 that informs Alphaserver of new ssh login attempts
def inform_alphaserver(client_message):
port = 7888
alphaserver_hostname = socket.gethostname()
alphaserver_ip = socket.gethostbyname(alphaserver_hostname)
print('Establishing connection with {} at port {} ...'.format(alphaserver_ip,port))
c = socket.socket()
print('Client socket created...')
c.connect((alphaserver_ip,port))
print('Client socket connected with {} at port {}'.format(alphaserver_ip, port))
client_message = client_message.encode()
print("Sending client message...")
c.send(client_message)
print("Message has been transmitted to alphaserver successfully")
c.close()
print("Connection Closed!!!")
#Monitor new ssh login attempts
while True:
#Function 1
current_ssh_attempts = ssh_attempts(input_file)
#Condition to test if new login attempts made
if current_ssh_attempts > total_ssh_attempts:
total_ssh_attempts = current_ssh_attempts
print('SSH login attempts detected!!!')
client_message = '{} had {} attempt'.format(socket.gethostname(), total_ssh_attempts)
#Function 2
#Send output file to Alphaserver
inform_alphaserver(client_message)
alphaserver.py
import os
import socket
#File for storing messages from Alphaclient
client_messages = os.path.join ('.','sshlogin-counter','client_messages.txt')
#Function that listens to client servers and receives client data
def receive_clientmessage():
port = 7888
host = socket.gethostname()
print('Binding {} at port {}'.format(host,port))
s = socket.socket()
print('Server Socket created.')
s.bind((host, port))
print('Server socket binded at port {}'.format(port))
s.listen(2)
print('Listening to port...')
while True:
c , addr = s.accept()
print("Connected with {}".format(addr))
client_message = c.recv(1024).decode()
client_hostname = list(str(client_message).split(" "))[0] #str converted to list and list[0] is the client_hostname
print("Client host name is {} ".format(client_hostname))
c.close()
break
#s.close()
return (client_hostname, client_message)
#Function to write client data to client_message.
def update_client_messages(client_hostname, client_message):
file = open(client_messages, 'r+')
f = file.read()
if client_hostname in f:
position = f.index(client_hostname)
file.seek(position)
file.write(str(client_message))
print('Updated client SSH login data')
file.close()
else:
file = open(client_messages,'a')
file.write('\n'+ str(client_message))
print('Added new client SSH login data')
file.close()
#Continuosly monitor and display client data
while True:
client_hostname, client_message = receive_clientmessage()
update_client_messages(client_hostname, client_message)
file = open(client_messages)
content = file.read()
print('----------------------------------------------------')
print(content)
print('----------------------------------------------------')
file.close()

Running server and client python scripts from a single python script or GUI button

I have been working with python server and client communication. In order to establish a connection, usually, the server needs to run 1st and then client from separate python scripts.
What I want now is to make it automated. I want to run both server and client from a single python script or a GUI button. I have been trying different ways like multiprocessing and multithreading but it is not working.
Please advice.
Sample server and client codes below:
Server.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('0.0.0.0', 5005))
s.listen(1)
conn, addr = s.accept()
while 1:
data = conn.recv(1024)
print("received data",list(data))
if not data:
break
conn.sendall(data)
conn.close()
Client.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('0.0.0.0', 5005))
message = bytearray([1])
s.sendall(message)
data = s.recv(1024)
s.close()
print ('Received', repr(data))
We can handle it by assigning two different functions. A few notes:
When two different threads are trying to print something in a same stream, they should acquire a common lock first so that they print something in order.
Server starts listening on "0.0.0.0" means it is ready to accept a connection from anywhere. On the other hand, when you're running the client side on your machine, you should connect to localhost or 127.0.0.1 instead of connecting to 0.0.0.0.
import threading
import socket
stream_lock = threading.Lock()
def server_func():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('0.0.0.0', 5005))
s.listen(1)
conn, addr = s.accept()
while 1:
data = conn.recv(1024)
# Getting printing stream lock is important
stream_lock.acquire()
print("received data", list(data))
stream_lock.release()
if not data:
break
conn.sendall(data)
conn.close()
def client_func():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1', 5005))
message = bytearray([1, 2, 3])
s.sendall(message)
data = s.recv(1024)
s.close()
stream_lock.acquire()
print('Received', repr(data))
stream_lock.release()
t_server = threading.Thread(target=server_func).start()
t_client = threading.Thread(target=client_func).start()
# Output:
# received data [1, 2, 3]
# Received b'\x01\x02\x03'
i convert #aminrd 's answer to class object and add some code to store received data from client also added some comments for who need to understand each step
import socket
import threading
import json
import time
class Communication:
stream_lock = threading.Lock() # creating thread lock object
def __init__(self):
self.clientSocket = None
self.serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # create socket and store
self.STORED_DATA = {"function_name": "", "data": ""} # sample stored data
self.th = [] # threads list
def server(self):
self.serverSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,
1) # make reusing adress with different port
self.serverSocket.bind(('0.0.0.0', 5005)) # bind socket with port
self.serverSocket.listen(2) # permitted client number
print("Server is listening")
while True:
client, address = self.serverSocket.accept() # welcome new client
# send client data to new thread and process
self.th.append(threading.Thread(target=self.listener, daemon=True, args=(client,)).start())
def listener(self, client):
while True:
data = client.recv(2048) # receive new data to store
if data:
# you can get data from any client and puch data to all clients(multiple status monitors)
data_variable = json.loads(data.decode('utf-8')) # decode byte to dict
self.stream_lock.acquire() # i'm not sure about usage of lock. wrong place ?
if 'command' in data_variable and data_variable['command'] == 'write':
self.STORED_DATA = data_variable
else:
# or you can do some server stuff and manipulate data
self.STORED_DATA['function_name'] = 1
self.STORED_DATA['data'] = 1
self.stream_lock.release()
data_string = json.dumps(self.STORED_DATA).encode('utf-8') # convert stored data to bytes
client.sendall(data_string) # now send stored data to all clients
def client(self):
self.clientSocket.connect(('127.0.0.1', 5005)) # connect to server
# this function is callable from outside of class
# you can give new data to client to send to server
def receive(self, new_data_string):
self.clientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # create socket for client
self.clientSocket.connect(('127.0.0.1', 5005)) # connect to server
data_string = json.dumps(new_data_string).encode('utf-8') # convert data to bytes
self.clientSocket.send(data_string) # send to server
data = self.clientSocket.recv(2048) # receive server data
if not data:
print("no data")
self.clientSocket.close()
data_variable = json.loads(data.decode('utf-8')) # convert data to dict
self.stream_lock.acquire()
self.stream_lock.release()
self.clientSocket.close()
return data_variable # return received data
if __name__ == "__main__":
x = Communication()
t_server = threading.Thread(target=x.server, daemon=True).start()
read = {"command": "read", "function_name": "", "data": ""}
result = x.receive(read)
print('Client Received', repr(result))
time.sleep(1)
write = {"command": "write", "function_name": "2", "data": "2"}
result = x.receive(write)
print('Client Received', repr(result))

Sending JSON object to a tcp listener port in use Python

I have a listener on a tcp localhost:
HOST = '127.0.0.1' # The server's hostname or IP address
PORT = 8192 # The port used by the server
def client_socket():
while 1:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP,TCP_PORT))
s.listen(1)
while 1:
print 'Listening for client...'
conn, addr = s.accept()
print 'Connection address:', addr
data = conn.recv(BUFFER_SIZE)
if data == ";" :
conn.close()
print "Received all the data"
i=0
for x in param:
print x
#break
elif data:
print "received data: ", data
param.insert(i,data)
i+=1
#print "End of transmission"
s.close()
I am trying to send a JSON object to the same port on the local host:
HOST = '127.0.0.1' # The server's hostname or IP address
PORT = 8192 # The port used by the server
def json_message(direction):
local_ip = socket.gethostbyname(socket.gethostname())
data = {
'sender' : local_ip,
'instruction' : direction
}
json_data = json.dumps(data, sort_keys=False, indent=2)
print("data %s" % json_data)
send_message(json_data)
return json_data
def send_message(data):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
s.sendall(data)
data = s.recv(1024)
print('Received', repr(data))
However, I get a socket error:
socket.error: [Errno 98] Address already in use
What am I doing wrong? Will this work or do I need to serialize the JSON object?
There are a few problems with your code, but the one that will likely address your issue is setting the SO_REUSEADDR socket option with:
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
after you create the socket (with socket.socket(...) but before you attempt to bind to an address (with s.bind().
In terms of other things, the two "halves" of the code are pretty inconsistent -- like you copied and pasted code from two different places and tried to use them?
(One uses a context manager and Python 3 print syntax while the other uses Python 2 print syntax...)
But I've written enough socket programs that I can decipher pretty much anything, so here's a working version of your code (with some pretty suboptimal parameters e.g. a buffer size of 1, but how else would you expect to catch a single ;?)
Server:
import socket
HOST = '127.0.0.1' # The server's hostname or IP address
PORT = 8192 # The port used by the server
BUFFER_SIZE = 1
def server_socket():
data = []
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST,PORT))
s.listen()
while 1: # Accept connections from multiple clients
print('Listening for client...')
conn, addr = s.accept()
print('Connection address:', addr)
while 1: # Accept multiple messages from each client
buffer = conn.recv(BUFFER_SIZE)
buffer = buffer.decode()
if buffer == ";":
conn.close()
print("Received all the data")
for x in data:
print(x)
break
elif buffer:
print("received data: ", buffer)
data.append(buffer)
else:
break
server_socket()
Client:
import socket
import json
HOST = '127.0.0.1' # The server's hostname or IP address
PORT = 8192 # The port used by the server
def json_message(direction):
local_ip = socket.gethostbyname(socket.gethostname())
data = {
'sender': local_ip,
'instruction': direction
}
json_data = json.dumps(data, sort_keys=False, indent=2)
print("data %s" % json_data)
send_message(json_data + ";")
return json_data
def send_message(data):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
s.sendall(data.encode())
data = s.recv(1024)
print('Received', repr(data))
json_message("SOME_DIRECTION")

audio over python tcp error

I am writing a simple python tcp code to send over a wav file however I seem to be getting stuck. can someone explain why my code is not working correctly?
Server Code
import socket, time
import scipy.io.wavfile
import numpy as np
def Main():
host = ''
port = 3333
MAX = 65535
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,port))
s.listen(1)
print "Listening on port..." + str(port)
c, addr = s.accept()
print "Connection from: " + str(addr)
wavFile = np.array([],dtype='int16')
i = 0
while True:
data = c.recvfrom(MAX)
if not data:
break
# print ++i
# wavfile = np.append(wavfile,data)
print data
timestr = time.strftime("%y%m%d-%h%m%s")
print timestr
# wavF = open(timestr + ".wav", "rw+")
scipy.io.wavfile.write(timestr + ".wav",44100, data)
c.close()
if __name__ == '__main__':
Main()
Client Code
host, port = "", 3333
import sys , socket
import scipy.io.wavfile
# create a tcp/ip socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# connect the socket to the port where the server is listening
server_address = (host, port)
print >>sys.stderr, 'connecting to %s port %s' % server_address
input_data = scipy.io.wavfile.read('Voice 005.wav',)
audio = input_data[1]
sock.connect(server_address)
print 'have connected'
try:
# send data
sock.sendall(audio)
print "sent" + str(audio)
sock.close()
except:
print('something failed sending data')
finally:
print >>sys.stderr, 'closing socket'
print "done sending"
sock.close()
Please help someone, I want to send an audio file to my embedded device with tcp since it crucial data to be processed on the embedded device.
Not sure why you go to the trouble of using scipy and numpy for this, since you can just use the array module to create binary arrays that will hold the wave file. Can you adapt and use the simple client/server example below?
(Note: I've copy/pasted a small Windows sound file called 'tada.wav' to the same folder to use with the test scripts.)
Code for the server script:
import socket
HOST = '' # Symbolic name meaning all available interfaces
PORT = 50007 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
print('Listening...')
conn, addr = s.accept()
print('Connected by', addr)
outfile = open("newfile.wav", 'ab')
while True:
data = conn.recv(1024)
if not data: break
outfile.write(data)
conn.close()
outfile.close()
print ("Completed.")
Code for the client:
from array import array
from os import stat
import socket
arr = array('B') # create binary array to hold the wave file
result = stat("tada.wav") # sample file is in the same folder
f = open("tada.wav", 'rb')
arr.fromfile(f, result.st_size) # using file size as the array length
print("Length of data: " + str(len(arr)))
HOST = 'localhost'
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.send(arr)
print('Finished sending...')
s.close()
print('done.')
This works for me (though only tested by running both on localhost) and I end up with a second wave file that's an exact copy of the one sent by the client through the socket.

Python: Send data to one client from database

I have a python script that receives tcp data from client and I want to send a response to a specific client (I handle more than 500). This command comes from a mysql database and I handle the clientsocket by a dictionary, but the script is down when it receives a lot of connections.
How can I store the clientsocket in mysql database, or which is the best way to handle the clientsocket?
My code is:
import thread
from socket import *
def sendCommand():
try:
for clientsocket,id_client in conn_dict.iteritems():
if id_cliente == "TEST_from_mysql_db":
clientsocket.send("ACK SEND")
break
except:
print "NO"
def handler(clientsocket, clientaddr):
print "Accepted connection from: ", clientaddr
while 1:
data = clientsocket.recv(buf)
if not data:
break
else:
conn_dict[clientsocket] = id_client
sendCommand()
clientsocket.close()
if __name__ == "__main__":
conn_dict = dict()
host = str("XXX.XXX.XXX.XXX")
port = XXX
buf = 1024
addr = (host, port)
serversocket = socket(AF_INET, SOCK_STREAM)
serversocket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
serversocket.bind(addr)
serversocket.listen(2)
while 1:
print "Server is listening for connections\n"
clientsocket, clientaddr = serversocket.accept()
thread.start_new_thread(handler, (clientsocket, clientaddr))
serversocket.close()

Categories