Recieving File Over TCP Socket in Python - java

I am trying to send a file over a TCP socket from a Java Client to a Python Server. I have been able to successfully transfer the file, but there is a problem with the server where it fails to recognize the end of the byte stream it is receiving from the client.
Here is my server:
import socket
server_addr = '127.0.0.1', 5555
# Create a socket with port and host bindings
def setupServer():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print("Socket created")
try:
s.bind(server_addr)
except socket.error as msg:
print(msg)
return s
# Establish connection with a client
def setupConnection(s):
s.listen(5) # Allows five connections at a time
print("Waiting for client")
conn, addr = s.accept()
return conn
def getFile(filename, conn):
print("Creating file", filename, "to write to")
with open(filename, 'wb') as f:
data = conn.recv(1024)
while data:
print(data)
f.write(data)
data = conn.recv(1024) #This is where the problem is
print("Finished writing to file")
# Loop that sends & receives data
def dataTransfer(conn, s):
while True:
# Recieve a file
print("Connected with:", s)
filename = "test.json"
getFile(filename, conn)
break
conn.close()
sock = setupServer()
while True:
try:
connection = setupConnection(sock)
dataTransfer(connection, sock)
except:
break
And here is the Java Client:
import java.io.*;
import java.net.*;
public class Client1
{
private Socket socket = null;
private FileOutputStream fos = null;
private DataInputStream din = null;
private DataOutputStream dos = null;
private PrintStream pout = null;
public Client1(InetAddress address, int port)
{
try {
System.out.println("Initializing Client");
socket = new Socket(address, port);
din = new DataInputStream(socket.getInputStream());
dos = new DataOutputStream(socket.getOutputStream());
pout = new PrintStream(socket.getOutputStream());
} catch (Exception ex) {
System.out.println(ex.getMessage());
System.exit(1);
}
}
public void send(String msg) throws IOException
{
pout.print(msg);
pout.flush();
}
public void closeConnections() throws IOException
{
// Clean up when a connection is ended
socket.close();
din.close();
dos.close();
pout.close();
scan.close();
}
public void sendFile(String filename)
{
System.out.println("Attempting to send file: "+filename);
try{
File file = new File(filename);
if(!file.exists()){
System.out.println("File does not exist. Aborting");
return;
}
//send(filename);
try (FileInputStream fis = new FileInputStream(file)) {
int count;
byte[] buffer = new byte[1024];
while( (count = fis.read(buffer)) > 0){
dos.write(buffer, 0 , count);
}
dos.flush();
}
} catch(IOException e){
e.printStackTrace();
}
}
}
The problem is the while loop in the server in the getFile() method. Specifically, the data = conn.recv(1024) inside the while loop seems to loop infinitely and data is never null. The while loop runs just the same as if it read while True: but it should break once the message ends and then close the connection. As I mentioned earlier, the data arrives correctly and the client exits cleanly, it's just that the server fails to detect that there is not more data incoming.
Any suggestions on how to get this loop working properly?

Related

Java socket file transfer - Connection reset

I'm trying to make a program that transfer a file using java sockets. This is what I've written so far:
Sender:
private ServerSocket sendSocket;
public Send(int port) throws IOException
{
sendSocket = new ServerSocket(port);
}
public void run()
{
Socket socket = null;
try
{
Scanner scan = new Scanner(System.in);
InputStream inStream = null;
socket = sendSocket.accept();
inStream = socket.getInputStream();
String filePath = scan.nextLine();
OutputStream thisFile = new FileOutputStream(filePath);
byte[] bytes = new byte[16*1024];
int count;
while ((count = inStream.read(bytes)) > 0)
{
thisFile.write(bytes, 0, count);
}
System.out.println("Done!");
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
Receiver:
private static OutputStream thatFile;
public Receive(Socket socket) throws IOException
{
thatFile = socket.getOutputStream();
}
public void run()
{
try
{
System.out.println("Where do you want to save the file?");
Scanner scan = new Scanner(System.in);
String filePath = scan.nextLine();
File saveFile = new File(filePath);
byte[] bytes = new byte[16 * 1024];
InputStream inStream = new FileInputStream(saveFile);
int count;
while ((count = inStream.read(bytes)) > 0)
{
thatFile.write(bytes, 0, count);
}
}
catch (Exception e)
{
}
}
}
But whenever I run the program, after the client gives a destination for the download path, connection reset error happens on the sender side. I'm sure the port is open as I've tested on this port before. What's the problem?
This is what happens when I run the program:
Sender side:
Press 1 to send or 2 to receive.
1
What is the file's path?
C:\Users\orie5\Documents\Cmp\a.txt
java.net.SocketException: Connection reset
at java.base/sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:323)
at java.base/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:350)
at java.base/sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:803)
at java.base/java.net.Socket$SocketInputStream.read(Socket.java:966)
at java.base/java.io.InputStream.read(InputStream.java:218)
at def.Send.run(Send.java:47)
Receiver Side:
Press 1 to send or 2 to receive.
2
Please enter the ip of the peer you want to connect to.
Where do you want to save the file?
C:\Users\orie5\Documents\Cmp\b.txt
Thanks in advance!

How to show error message if Server does not have a file requested by client TCP using java

I have to write java project for TCP Client/Server. The goal of the code is the Client asks server about a file. if the file is available it will be saved into client directory and show message the file is found and saved otherwise, the file is not found.
the code works when the file is in the Server directory and it will be saved in the client directory but if the file is not available it will show message in server side the file not available but in Client side it will save a new empty file with the name of the file that not available and message the File received
Can you help please
I have Server code
import java.io.*;
import java.net.*;
import java.util.*;
//********************
public class Server
{
static ServerSocket ServSock;
static int QLen = 6;
//***
public static void main(String args[])
{
try
{
//*** establish server socket
ServSock = new ServerSocket(Integer.parseInt(args[0]), QLen);
while (true)
{
//*** accept a client
Socket Sock = ServSock.accept();
//*** pass the client to a new thread
new Worker(Sock).start();
}
}
catch(IOException e)
{System.out.println(e);}
}
}
//*************************
class Worker extends Thread
{
Socket Sock;
PrintWriter PW;
BufferedReader DIS;
String Question = "Enter the file name to transfer from server:";
//**************
Worker(Socket S)
{Sock=S;}
//**************
public void run()
{
try
{
//*** thread identifies itself
System.out.println("Thread: " + getName());
//*** auto-flush
//*** set up socket I/O streams
PW = new PrintWriter (new BufferedWriter (new OutputStreamWriter(Sock.getOutputStream())),true);
DIS = new BufferedReader (new InputStreamReader (Sock.getInputStream()));
//*** send server question
PW.println(Question);
//*** wait for client response
String R = DIS.readLine();
Scanner in = null;
try{
BufferedOutputStream put=new BufferedOutputStream(Sock.getOutputStream());
BufferedReader st=new BufferedReader(new InputStreamReader(Sock.getInputStream()));
String str = "/Users/Batool/Desktop/HW/Server/";
String path = str + R;
System.out.println("The requested file is path: "+path);
System.out.println("The requested file is : "+R);
File f=new File(path);
System.out.println(f.isFile());
if(f.isFile())
{
//System.out.println("inside if");
FileInputStream fis=new FileInputStream(f);
System.out.println("File transfered");
System.out.println("———————————————————————————————");
byte []buf=new byte[1024];
int read;
while((read=fis.read(buf,0,1024))!=-1)
{
put.write(buf,0,read);
put.flush();
}
}//end if
else{ System.out.println("File not found");
System.out.println("———————————————————————————————");}//end else
}//end try
catch(FileNotFoundException e)
{
System.out.println(e.getMessage());
//System.exit(0);
}//end catch
//*** close this socket connection
Sock.close();
}
catch(IOException e)
{System.out.println(e);}
}
}
and I have Client code
import java.io.*;
import java.net.*;
import java.util.*;
public class Client
{
static Socket sock;
static PrintWriter pw;
static BufferedReader br;
static String response = "";
//************************************
public static void main(String args[]) throws IOException
{
//*** establish connection to remote server
sock = new Socket(args[0],
Integer.parseInt(args[1])); //*** provide server name & port
//*** set up socket I/O streams
pw = new PrintWriter (new BufferedWriter (new OutputStreamWriter(sock.getOutputStream())),true);
br = new BufferedReader (new InputStreamReader (sock.getInputStream()));
//*** wait for server question
String r = br.readLine(); //*** THIS IS A BLOCKING CALL
System.out.println("Server asks: " + r);
//*** respond to server
/*Scanner in = new Scanner(System.in);
String s = in.nextLine();
pw.println(s);
pw.flush();
*/
Socket s=null;
BufferedInputStream get=null;
PrintWriter put=null;
try
{
get=new BufferedInputStream(sock.getInputStream());
put=new PrintWriter(sock.getOutputStream(),true);
String f;
int u;
//System.out.println("Enter the file name to transfer from server:");
DataInputStream dis=new DataInputStream(System.in);
f=dis.readLine();
put.println(f);
File f1=new File(f);
String str = "/Users/Batool/Desktop/HW/Client";
FileOutputStream fs=new FileOutputStream(new File(str,f1.toString()));
System.out.println(new File(str,f1.toString()));
System.out.println(f1.isFile());
byte jj[]=new byte[1024];
while((u=get.read(jj,0,1024))!=-1)
{
fs.write(jj,0,u);
}
fs.close();
System.out.println("File received");
System.out.println("———————————————————————————————");
sock.close();
}catch(Exception e)
{
System.out.println("File not found");
System.out.println("———————————————————————————————");
e.printStackTrace();
System.exit(0);
}
//*** close this socket connection
//sock.close();
}
}
Basically you need to implement a protocol.
Client asks server: do you have file X?
a) Servers says: yes, I got xyz bytes for you, and the md5sum is zyx
Then your client asks for the file; and it can verify it got the correct amount of bytes and that no transmission errors happened. (of course you don't need that verification part; but depending on your context, those are things that you should consider to have in place, too)
b) Server says: no, I don't have that file
Then your client gives an error message to its user.
In other words: the server just reading files and pushing bytes out will not do!
You want to turn your server into something that offers services. And a service has a contract, such as "input" and "output". And services need ways to "negotiate" what should happen next. In your current solution, everything that happen is hardcoded - meaning there is already a protocol in place, but that protocol is defined by the instructions that you put into your code!

Changes made to .properties file do not reflect in java

I have written a TCP Client program which calls the properties file and takes the values from there. When I run the TCPClient for the first time, it runs properly and sends all the data values of server.properties file to the server, but as soon as I try to add one more data "data4" to server.properties file my project gets a "x" mark and the changes made in server.properties file don't reflect and I get Error: cannot find or load class TCPClient.
I tried to create a new project, still the same, the changes made to properties file do not reflect. Can someone kindly help me on this. Thanks in advance
public class TCPClient {
private static Socket socket;
public String getPropertyValues() throws IOException{
String result="";
Properties prop = new Properties();
String propFileName = "server.properties";
InputStream inputStream = getClass().getClassLoader().getResourceAsStream(propFileName);
prop.load(inputStream);
try
{
String host = prop.getProperty("host");
System.out.println(host);
int port = Integer.parseInt(prop.getProperty("port"));
System.out.println(port);
String data = prop.getProperty("data");
System.out.println(data);
InetAddress address = InetAddress.getByName(host);
socket = new Socket(address, port);
//Send the message to the server
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
String sendMessage = data;
bw.write(sendMessage);
bw.flush();
System.out.println("Message sent to the server : "+sendMessage);
//Get the return message from the server
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String message = br.readLine();
System.out.println("Message received from the server : " +message);
}
catch (Exception exception)
{
exception.printStackTrace();
}
finally
{
//Closing the socket
try
{
socket.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
return result;
}
public static void main(String[] args) throws IOException{
TCPClient properties = new TCPClient();
properties.getPropertyValues();
}
}
I have a properties file by name server.properties
data = data1
data2
data3
port = 3035
host = localhost
When ever I make change to the data field of this properties file and save, the project turns with a "x" mark and when I try to run the TCPClient program using Run as-->JavaApplication, I get the pop up as
Errors exist in required project
Test
Proceed with Launch?

Null pointer exception occurs while trying to read repeatedly from an InputStream

The code works fine when I close the client just after sending one instruction. But when I want a client and server connection to persist, so that the client can send multiple instructions to the server one after another, I get a Null pointer exception at the server and the message java.net.SocketException: Socket is closed at the client. This happens after the client sends a file to the server and the server successfully receives it. Need help. The error occurs at the Connection class code line switch(clientMsg). It seems to me that for some reason the BufferedReader in goes null, but I might be mistaken about that. The code is as follows. Thanks.
Server
public class server {
private static ServerSocket serverSocket;
private static Socket socket = null;
public static void print(Object s) {
System.out.println(s);
}
#SuppressWarnings("resource")
public static void main (String args[]) throws IOException {
System.out.print("Specify listening port: ");
Scanner _a = new Scanner(System.in);
int a = _a.nextInt();
try{
serverSocket = new ServerSocket(a);
}
catch(IOException e) {
System.out.println(e);
}
while (true) {
try {
socket = serverSocket.accept();
print("Connected to " + socket);
Thread client = new Thread(new Connection(socket));
client.start();
}
catch (IOException e) {
print(e);
}
}
}
}
Connection
public class Connection implements Runnable {
public static void print(Object s) {
System.out.println(s);
}
private Socket socket;
private BufferedReader in = null;
public Connection(Socket client) {
this.socket = client;
}
#Override
public void run(){
try {
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
String clientMsg;
while (true) {
clientMsg = in.readLine();
switch (clientMsg) {
case "1":
receiveFile(); //method code not included
break;
default:
print("Command not recognized");
break;
}
//in.close();
}
}//try run()
catch (IOException e) {
print(e);
}
}
Client
public class client {
private static Socket connectToServer;
private static String fileName;
private static BufferedReader keybrdIn;
private static PrintStream msgToServer;
public static void println(Object e) {
System.out.println(e);
}
public static void print(Object e) {
System.out.print(e);
}
public static void main(String args[]) throws IOException{
try{
print("Enter IP: ");
String ip = new Scanner(System.in).nextLine();
print("Enter port: ");
int port = new Scanner(System.in).nextInt();
connectToServer = new Socket(ip, port);
keybrdIn = new BufferedReader(new InputStreamReader(System.in));
}catch(IOException e) {
println(e);
}
msgToServer = new PrintStream(connectToServer.getOutputStream());
while (true) {
try {
switch(Integer.parseInt(action())) { //action() method code not included
case 1:
msgToServer.println("1");
sendFile();
break;
default:
println("Invalid input");
break;
}
}catch (IOException e) {
println(e);
}
}
}
sendFile()
public static void sendFile() throws IOException {
print("Enter file name: ");
fileName = keybrdIn.readLine();
File file = new File(fileName);
byte[] bytearray = new byte[8192];
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
DataInputStream dis = new DataInputStream(bis);
OutputStream os = connectToServer.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
dos.writeUTF(file.getName());
int count;
while ((count = dis.read(bytearray)) > 0){
dos.write(bytearray, 0, count);
}
dis.close();
dos.flush();
dos.close();
}
receiveFile()
public void receiveFile() {
try {
int count;
DataInputStream clientFileStream = new DataInputStream(socket.getInputStream());
String fileName = clientFileStream.readUTF();
OutputStream fileOutput = new FileOutputStream("_" + fileName);
byte[] mybytearray = new byte[8192];
BufferedOutputStream bos = new BufferedOutputStream(fileOutput);
System.out.println("Downloading " + fileName + " ...");
//outToClient().writeBytes("Uploading. Please wait...\n");
while ((count = clientFileStream.read(mybytearray)) > 0){
bos.write(mybytearray, 0, count);
}
fileOutput.close();
bos.close();
clientFileStream.close();
}
catch (IOException e) {
print(e);
}
}
In sendFile(), you close the data output stream which closes your underlying connection's output stream.
According to the documentation of Socket.getOutputStream():
"Closing the returned OutputStream will close the associated socket".
Since you already closed stream, it will also close socket as well as Eyal mentioned. However, at the moment you close the stream, server side will aware of that and return -1 for read() results.
So, even if you didn't specify file length at beginning, this will generally works well.
However, since you already closed stream, you can't reuse it no matter what. To fix this issue, probably you need to change your Client class so that Client should create socket connection, send files, close socket. That's one lifecycle of opened client socket.
Or maybe in while loop of Client class, 1) take ip, port, and filename to send 2) Create new Thread and provide those information so let thread open connection, send file, close connection 3) and in the meantime, client while() can keep take next ip, port, and filename to send from the user. By doing this, you don't need to make client program wait until file transfer to be completed.
Regarding the NPE in the server, readLine() returns null at end of stream. You are ignoring it. You should be testing for it immediately after the call, and if null close the socket and exit the read loop.

Implementation of a simple file transfer client server

Hi I have the following code to the client - server through the thread, I have a errors,
Can't setup server on this port number.
Can't setup server on this port number.
but why?
class client:
import java.io.*;
import java.net.Socket;
// create class client
public class Client extends Thread {
Socket socket = null;
Socket socket1 = null;
// create send method
public void sendFile() throws IOException {
String host = "127.0.0.1";
String host1 = "127.0.0.2";
socket = new Socket(host, 4444);
socket1 = new Socket(host1, 444);
File file = new File("/home/reza/Desktop/link help");
File file1 = new File("/home/reza/Desktop/hi");
long length = file.length();
long length1 = file1.length();
byte[] bytes = new byte[(int) length];
byte[] bytes1 = new byte[(int) length1];
FileInputStream fis = new FileInputStream(file);
FileInputStream fis1 = new FileInputStream(file1);
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream());
BufferedInputStream bis1 = new BufferedInputStream(fis1);
BufferedOutputStream out1 = new BufferedOutputStream(socket1.getOutputStream());
int count;
int count1;
while ((count = bis.read(bytes)) > 0) {
out.write(bytes, 0, count);
}
while ((count1 = bis1.read(bytes1)) > 0) {
out1.write(bytes1, 0, count1);
}
Thread t = new Thread(new Runnable() {
public void run()
{
while(socket.isConnected())
{
Wait2();
try {
sendFile();
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
Thread t1 = new Thread(new Runnable() {
public void run() {
while(socket1.isConnected())
{
Wait2();
try {
sendFile();
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
t.start();
t1.start();
fis.close();
fis1.close();
out.close();
bis.close();
out1.close();
bis1.close();
socket.close();
socket1.close();
}
public void Wait2()
{
try {
Thread.currentThread().sleep(3000);
} catch (InterruptedException x) {
System.out.println("Interrupted!");
}
}
}
// class server
import java.io.*;
import java.net.*;
public class Server {
public void recivefile() throws IOException {
ServerSocket serverSocket = null;
ServerSocket serverSocket1 = null;
try {
serverSocket = new ServerSocket(4444);
//serverSocket1 = new ServerSocket(444);
} catch (IOException ex) {
System.out.println("Can't setup server on this port number. ");
}
try {
serverSocket1 = new ServerSocket(444);
} catch (IOException ex) {
System.out.println("Can't setup server on this port number. ");
}
Socket socket = null;
Socket socket1 = null;
InputStream is = null;
InputStream is1 = null;
FileOutputStream fos = null;
FileOutputStream fos1 = null;
BufferedOutputStream bos = null;
BufferedOutputStream bos1 = null;
int bufferSize = 0;
int bufferSize1 = 0;
try {
socket = serverSocket.accept();
socket1 = serverSocket1.accept();
} catch (IOException ex) {
System.out.println("Can't accept client connection. ");
}
try {
is = socket.getInputStream();
is1 = socket1.getInputStream();
bufferSize = socket.getReceiveBufferSize();
bufferSize1 = socket1.getReceiveBufferSize();
System.out.println("Buffer size: " + bufferSize);
System.out.println("file recieved");
System.out.println("Buffer size1: " + bufferSize1);
System.out.println("file recieved");
System.out.println("file recieved");
} catch (IOException ex) {
System.out.println("Can't get socket input stream. ");
}
try {
fos = new FileOutputStream("/home/reza/Desktop/reza");
bos = new BufferedOutputStream(fos);
fos1 = new FileOutputStream("/home/reza/Desktop/ali");
bos1 = new BufferedOutputStream(fos1);
} catch (FileNotFoundException ex) {
System.out.println("File not found. ");
}
byte[] bytes = new byte[bufferSize];
int count;
while ((count = is.read(bytes)) > 0) {
bos.write(bytes, 0, count);
}
byte[] bytes1 = new byte[bufferSize1];
int count1;
while ((count1 = is1.read(bytes1)) > 0) {
bos1.write(bytes1, 0, count1);
}
bos.flush();
bos.close();
bos1.flush();
bos1.close();
is.close();
is1.close();
socket.close();
serverSocket.close();
socket1.close();
serverSocket1.close();
}
public static void main(String[] args) throws IOException
{
System.out.println("server is run, please send file");
Server s = new Server();
s.recivefile();
}
}
error is :
Can't setup server on this port number.
Can't setup server on this port number.
You can't start a server on 127.0.0.2 - therein lies your problem.
netstat -ano | find "1024"
try above command if you are running your java files on windows environment that will help you to find any process using same port no as yours and also use
ex.printStackTrace() along with
System.out.println("Can't setup server on this port number.");
Assuming that your code runs on a unix platform, your server code is trying twice to open a socket on port 444, which is a system reserved port. In order to be able to succeed, your programme must run with administrative priviledges, and you must ensure that the port is not already used by another process.
A possible workaround is to:
use a port above 1024. These ports are free to use for userland programmes
in case of failure have a backup port, also above 1024. You must amend both server and client codes to try both ports, and of course your communication protocol must include some form of handshaking to make sure they are talking to the right interlocutor.
There are many other problems with your code listed in other answers.
you don't need to make every objects twice. Only one instance is enough in most cases,
if your server is running continuously and must accept many connections, you should not close the accepting socket at the end of one receiving session.
also the server is supposed to run a loop on the server socket accept call, and start a new thread for each incoming connection, whose job is to handle that connection.
While I understand your willingness to learn and experiment, there are existing solutions to what you are trying to achieve. For instance, you could simply use a FTP server for your purpose.
The way you have written client - server program is wrong I guess.
Following are the mistakes you have done...
1) In Client class, you have sendFile function in which you've created two threads - t & t1. In run function you are again calling the same sendFile function.
So it keeps creating threads under threads just like recursion.
2) In Server class, you are listening to two port within the same recieveFile function. As the socket = serverSocket.accept() is a blocking call, It wont excecute the rest of the code untill it finds a single client to connect.
So what exactly happens here is.. Once the first client connects, thenafter immediately it expects second client to connect.
In the mean time your client thread may try to access the port on which connection has not been established.
In short, your SERVER SHOULD BE IN A THREADING ENVIRONMENT NOT THE CLIENT.
And I would suggest that for different port you should use different server.
i.e. create different server class for both 1024 & 1025 port.

Categories