How to receive plain Text through Socket in Java - java

I was trying to send plain text through Socket. So I found a post in StackOverflow, I followed it and I guess it that I did it write However, How can I accept that plain text as string in the client?
I used BufferedReader() and InputStreamReader() class, but exception has been thrown.
Exception : exception java.net.SocketException: Broken pipe
Here is the code:
Server:
OutputStreamWriter osw = new OutputStreamWriter(socket.getOutputStream(), "UTF-8");
osw.write(fileName, 0, fileName.length());
Client:
InputStream in = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String fileName = br.readLine();
br.close();
Some help would be great. :) Thank you.
Client side code:
public void soc_client() throws Exception {
long time = System.currentTimeMillis();
long totalRecieved = 0;
try {
Socket sock = new Socket("172.16.27.106", 55000);
System.out.println("Hello Client");
InputStream in = sock.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String fileName = br.readLine();
File outputFile = new File(fileName + "");
br.close(); // CLOSING BufferedReader
FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
byte[] buffer = new byte[100 * 1024];
int bytesRead = 0;
while ((bytesRead = in.read(buffer)) != -1) {
fileOutputStream.write(buffer, 0, bytesRead);
totalRecieved += bytesRead;
System.out.println("Recieved " + (totalRecieved / 1024)
+ " kilobytes in "
+ ((System.currentTimeMillis() - time) / 1000)
+ " seconds");
}
fileOutputStream.close();
sock.close();
} catch (Exception e) {
System.out.println("Exception " + e);
} finally {
System.out.println("Recieved " + totalRecieved + " bytes in "
+ (System.currentTimeMillis() - time) + "ms.");
}
}

You're reading a line but you aren't sending a line, and you aren't closing the OutputWriter either. So readLine() will block forever waiting for a line terminator or an EOS that is never coming.
Add a newline to the message.
Close the OutputWriter.

Well to use sockets to send and transfer text in client server fashion , i'm posting a simple basic code , which upon running send a HELLO WORLD response to client.
//Server Side
ServerSocket server= new ServerSocket(1166); // //1166 -port no. u can use any other too.
Socket s= server.accept(); // makes a connection whenever a client requests.
OutputStream os= socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
dos.writeUTF("Hello World");
dos.close();
// Client Side
Socket socket= new Socket("Ip address of you server" , 1166) ;
InputStream is= new InputStream();
DataInputStream dis = new DataInputStream(is);
String msg=dis.readUTF();
System.out.println(msg);
dis.close();
now after you run the code once on server computer , then run the client side code and the server will now respond you with Hello World.

Related

Domain fronting proxy in Java, won't get "pull method" proxy to work

I'm currently working on a project that uses a technique called "domain fronting". In short: it send internet traffic to a CDN (in this case Google) over an encrypted connection, and the CDN then passes back this info to the proxy. This way you can circumvent censorship (as long a the CDN isn't blocked), because the real destination is unknown to a observer. (To read more about domain fronting, here is the original paper) A number of applications like Signal and Tor already use this technique, but there isn't a general use proxy that just proxies a tcp socket through Google to the other end. I decided to go work on that and it's almost finished: the HTTP encoding part and the code at Google's servers is working. The only problem is the real proxying part.
This is the structure of the proxy:
source-->client proxy-->[Google]-->server proxy-->destination
The difference with a general proxy is that HTTP is a request based protocol and thus can't do the asynchronous things normal proxies do. My setup is to make a request from the client once in 100ms to the server sending the bytes the client received to the server. The server reads the bytes from the destination and sends them back to the client. Than the server and client both write their received bytes to the original sockets and another roundtrip starts in 100ms.
Here is my code to this point (I only pasted the relevant part, this code is not domain fronting yet):
Client:
try {
ServerSocket serverSocket = new ServerSocket(8082);
System.out.println("client proxy is listening for connections");
Socket source = serverSocket.accept();
BufferedReader sourceIn = new BufferedReader(new InputStreamReader(source.getInputStream()));
PrintWriter sourceOut = new PrintWriter(source.getOutputStream(), false);
while(true) {
Socket server = new Socket("localhost", 8081);
BufferedReader in = new BufferedReader(new InputStreamReader(server.getInputStream()));
PrintWriter out = new PrintWriter(server.getOutputStream(), false);
//read what the source has for the server
System.out.println("start reading source socket");
System.out.println("available: " + source.getInputStream().available());
char[] buffer = new char[15000];
int bytesRead = 0;
if(source.getInputStream().available() != 0) {
bytesRead = sourceIn.read(buffer);
byte[] bytesToSend = new byte[bytesRead];
bytesToSend = Arrays.copyOfRange(new String(buffer).getBytes(), 0, bytesRead);
out.print((byte) 1);
out.print(bytesToSend);
out.flush();
System.out.println("Sent to server: " + new String(bytesToSend) + " bytesRead: " + bytesRead);
} else {
out.print((byte) 0);
out.flush();
System.out.println("Sent to server: nothing");
}
//read what the server has for the source
buffer = new char[15000];
bytesRead = 0;
while((bytesRead = in.read(buffer)) == -1) {
System.out.println("didn't receive any bytes from server");
Thread.sleep(20);
}
byte[] bytesToSend = Arrays.copyOfRange(new String(buffer).getBytes(), 0, bytesRead);
if(bytesToSend[0] == '1') {
sourceOut.print(bytesToSend);
sourceOut.flush();
System.out.println("Sent to source: " + new String(bytesToSend));
} else {
System.out.println("Server has nothing for source; bytesToSend: " + new String(bytesToSend));
}
in.close();
out.close();
server.close();
Thread.sleep(100);
}
} catch (Exception e) {
e.printStackTrace();
}
Server:
try {
Socket destination = new Socket("192.168.0.150", 22);
BufferedReader destinationIn = new BufferedReader(new InputStreamReader(destination.getInputStream()));
PrintWriter destinationOut = new PrintWriter(destination.getOutputStream(), false);
ServerSocket server = new ServerSocket(8081);
while(true) {
Socket clientSocket = server.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), false);
System.out.println("received new connection from client");
//read what client has for destination
char[] buffer = new char[15000];
int bytesRead = 0;
while((bytesRead = in.read(buffer)) == -1) {
System.out.println("didn't receive any bytes from client");
Thread.sleep(20);
}
byte[] bytesToSend = Arrays.copyOfRange(new String(buffer).getBytes(), 0, bytesRead);
if(bytesToSend[0] == (byte) 1) {
destinationOut.print(bytesToSend);
destinationOut.flush();
System.out.println("Sent to destination: " + new String(bytesToSend));
} else {
System.out.println("Client has nothing for destination");
}
//read what distination has for client
System.out.println("start reading destination socket");
System.out.println("available: " + destination.getInputStream().available());
buffer = new char[15000];
if(destination.getInputStream().available() != 0) {
bytesRead = destinationIn.read(buffer);
bytesToSend = new byte[bytesRead];
bytesToSend = Arrays.copyOfRange(new String(buffer).getBytes(), 0, bytesRead);
out.print("1");
out.print(new String(bytesToSend));
out.flush();
System.out.println("Sent to client: " + new String(bytesToSend) + " bytesRead: " + bytesRead);
} else {
out.print((byte) 0);
out.flush();
System.out.println("Sent to client: nothing");
}
out.close();
in.close();
clientSocket.close();
}
} catch (Exception e) {
e.printStackTrace();
}
When I run this code to connect to a SSH server, the SSH client freezes and it seems like the proxy server doesn't respond to the proxy client anymore.
I really hope someone can help me with this, if you need extra info, just let me know! :)

UDP File Transfer Java

I know UDP is not reliable and should not be used to send files but I have been asked to do that inside of a small part of an application for a small college assignment. For some reason my application freezes when I run the code to upload a file from client to server. Could anyone please help tell me what I'm doing wrong?
Client:
String hostName = hostNameTxt.getText();
String portAsString = portNumTxt.getText();
int portNum = Integer.parseInt(portAsString);
String sentFilePath = "c:/Documents/test.txt";
FileInputStream fis = null;
BufferedInputStream bis = null;
OutputStream os = null;
ServerSocket servsock = null;
Socket sock = null;
try {
servsock = new ServerSocket(portNum);
while (true) {
System.out.println("Waiting...");
try {
sock = servsock.accept(); //failing here I think
System.out.println("Accepted connection : " + sock);
// send file
File myFile = new File (sentFilePath);
byte [] mybytearray = new byte [(int)myFile.length()];
fis = new FileInputStream(myFile);
bis = new BufferedInputStream(fis);
bis.read(mybytearray,0,mybytearray.length);
os = sock.getOutputStream();
System.out.println("Sending " + sentFilePath + "(" + mybytearray.length + " bytes)");
os.write(mybytearray,0,mybytearray.length);
os.flush();
System.out.println("Done.");
}
finally {
if (bis != null) bis.close();
if (os != null) os.close();
if (sock!=null) sock.close();
}
}
}
catch (IOException ex) {
Logger.getLogger(Client1Interface.class.getName()).log(Level.SEVERE, null, ex);
System.out.println(ex);
} finally {
if (servsock != null) try {
servsock.close();
} catch (IOException ex) {
Logger.getLogger(Client1Interface.class.getName()).log(Level.SEVERE, null, ex);
}
}
Server:
String recievedFilePath = "c:/Documents/source.txt";
String hostName = "localhost";
int portNum = 7;
int fileSize = 6022386;
try{
int bytesRead;
int current = 0;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
Socket sock = null;
try {
sock = new Socket(hostName, portNum);
System.out.println("Connecting...");
// receive file
byte [] mybytearray = new byte [fileSize];
InputStream is = sock.getInputStream();
fos = new FileOutputStream(recievedFilePath);
bos = new BufferedOutputStream(fos);
bytesRead = is.read(mybytearray,0,mybytearray.length);
current = bytesRead;
do {
bytesRead =
is.read(mybytearray, current, (mybytearray.length-current));
if(bytesRead >= 0) current += bytesRead;
} while(bytesRead > -1);
bos.write(mybytearray, 0 , current);
bos.flush();
System.out.println("File " + recievedFilePath
+ " downloaded (" + current + " bytes read)");
}
finally {
if (fos != null) fos.close();
if (bos != null) bos.close();
if (sock != null) sock.close();
}
}
catch(Exception ex){
ex.printStackTrace( );
System.out.println("Error Uploading File");
}
You should try to use another port. The IP port 7 is blocked for the echo service, which will simply send you the same data back.
You should use ports above 1024. Otherwise you need superuser right from you OS to use this port.
The naming of you app is a little bit confusing. Normally the server should provide a ServerSocket on a not already used port and listen. The client must connect with a regular Socket to this port and send the data.
I've been testing your program (both server and client running in the same host), and it works. Still, I've to warn you about some important details (basically all of them have been already told in comments):
Conceptual details
The APIs chosen (java.net.Socket and java.net.ServerSocket) are TCP socket implementations, and not UDP. The UPD APIs are java.net.DatagramSocket and java.net.DatagramPacket.
The first program is no doubt the server, and the second is the client.
Technical details
You have to start first the server, and then, the client.
Server and client must run on different JVMs, so you have to run each one on a different process, either in a command shell or either by running it from your IDE.
(as Lars Repenning said) You have to use any available port over 1024, for example 3000.
Minor technical details
Do not allocate a buffer as big as the file size. To write the data out to a File, you should use the buffering technique: Use a small buffer (4096 bytes or multiple) and on each iteration, fill it with InputStream.read and write it with OutputStream.write. You will avoid memory problems and also will save yourself the need to know a priori the file size.

Java socket - the server response is always null

I have to connect with a server (I donĀ“t have access to the server code) but the transmission protocol (Socket) is:
(client) --> data
ack <-- (server)
data response <-- (server)
(client) --> ack
It's assumed that the server should always respond quickly. I connect to the server, I send the data but the response is NULL and if I debug my code, an exception occurs when I catch the response:
"java.net.SocketException: Software caused connection abort: recv failed"
My code:
public static void main(String[] args){
try{
String order = "datahere";
String responseServer;
BufferedReader inFromUser = new BufferedReader( new InputStreamReader(System.in));
Socket clientSocket = new Socket();
InetSocketAddress sa = new InetSocketAddress("XXX.XX.XX.XX", 9300);
clientSocket.connect(sa,500);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
outToServer.writeBytes(order);
responseServer = inFromServer.readLine();//exception if I try to debug my code
System.out.println("From server: " + responseServer); //responseServer is NULL
clientSocket.close();
} catch (IOException ex) {
System.out.println("Error: "+ex);
}
}
That's wrong? Any idea?
I tried to disable the firewall and also add a rule for the port 9300 but the result is the same.
The client gave me an example code in Vb.Net that it's supposed to work and I try to replicate it in Java.
Code in Vb.Net:
Dim message As String = "datahere";
Try
Dim data As [Byte]() = System.Text.Encoding.ASCII.GetBytes(message)
Dim client As New TcpClient(ip, port)
Dim stream As NetworkStream = client.GetStream()
stream.Write(data, 0, data.Length)
data = New [Byte](2048) {}
Dim responseData As [String] = [String].Empty
Dim bytes As Integer = stream.Read(data, 0, data.Length)
responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes)
stream.Close()
client.Close()
Catch ex As Exception
End Try
SOLUTION:
Socket clientSocket = new Socket();
InetSocketAddress sa = new InetSocketAddress("XXX.XX.XX.XX", 9300);
clientSocket.connect(sa,500);
clientSocket.getOutputStream().write(order.getBytes("ASCII"));
byte[] data = new byte[2048];
int bytes = clientSocket.getInputStream().read(data, 0, data.length);
String responseData = new String(data, 0, bytes, "ASCII");
System.out.println("From server: " + responseData);
//Another way to catch the response:
//InputStreamReader in = new InputStreamReader(clientSocket.getInputStream());
//int data1 = in.read();
//while(data1 != -1) {
// System.out.print((char) data1);
// data1 = in.read();
//}
clientSocket.close();
Here is a translation of your VB code in java
public static void main(String[] args) throws IOException {
String order = "datahere";
// Try-with-resource statement will close your socket automatically
try (Socket clientSocket = new Socket("XXX.XX.XX.XX", 9300)) {
// Send to the sever the order encoded in ASCII
clientSocket.getOutputStream().write(order.getBytes("ASCII"));
// Sleep until we have bytes to read available
while (clientSocket.getInputStream().available() == 0) {
Thread.sleep(100L);
}
// Create the buffer of exactly the amount of bytes available without blocking
byte[] data = new byte[clientSocket.getInputStream().available()];
// Read the bytes from the server and put it into the buffer
int bytes = clientSocket.getInputStream().read(data, 0, data.length);
// Decode what has been read from the server that was encoded in ASCII
String responseData = new String(data, 0, bytes, "ASCII");
System.out.println("From server: " + responseData);
}
}
DataInputStream dis = new DataInputStream( new InputStreamReader(clientSocket.getInputStream()));
while(dis.available()>0){
//reads characters encoded with modified UTF-8
String temp = dis.readUTF();
System.out.print(temp+" ");
}
try to use a dataInputStream instead of bufferedReader and use readUTF() method in dataInputStream to read UTF characters.

Sending file details over java socket fails

The code below is part of a larger attempt; it tries to transfer a file's details between server and client and fails miserably. Server writes 3 elements to socket, client should receive same 3 elements. Client blocks after reading first element. What am I doing wrong?!?
public class SocketIssues {
static void client() throws Exception {
new Thread() {
#Override
public void run() {
try {
Thread.sleep(1000); // enough time for server to open its socket
Socket s = new Socket("localhost", 50001);
final DataInputStream dis = new DataInputStream(s.getInputStream());
final BufferedReader in = new BufferedReader(new InputStreamReader(dis));
System.out.println("CLIENT STARTED");
System.out.println("Operation: " + in.readLine());
System.out.println("Length: " + dis.readLong());
System.out.println("Name: " + dis.readUTF());
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
static void server() throws Exception {
ServerSocket ss = new ServerSocket(50001);
Socket s = ss.accept();
System.out.println("SERVER: client connected");
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(dos));
long l = 2194;
String nume = "The file name";
out.write("FILE1" + System.lineSeparator());
out.flush();
dos.writeLong(l);
dos.flush();
dos.writeUTF(nume);
dos.flush();
System.out.println("SERVER: done sending" + System.lineSeparator());
}
public static void main(String[] args) throws Exception {
client();
server();
}
}
Try sticking with just the DataOutputStream instead of mixing them up between data and a buffered writer and use the read/write UTF() method like you're already doing with the last object:
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
long l = 2194;
String nume = "The file name";
dos.writeUTF("FILE1");
dos.flush();
dos.writeLong(l);
dos.flush();
dos.writeUTF(nume);
dos.flush();
System.out.println("SERVER: fisier trimis" + System.lineSeparator());
then in the client:
final DataInputStream dis = new DataInputStream(s.getInputStream());
System.out.println("CLIENT STARTED");
System.out.println("Operation: " + dis.readUTF());
System.out.println("Length: " + dis.readLong());
System.out.println("Name: " + dis.readUTF());
Essentially, there's 2 layers of buffering going on. It's possible that when you call readLine() from the BufferedReader, it goes ahead and steals more bytes from the underlying stream because, well, that's what it's supposed to do. Then, when you go back to the DataInputStream and try to read an object, the preamble is gone (BufferedReader stole it), and it'll block waiting for it, eventhough there's bytes in the stream.

Writing a simple HTTP server to accept GET requests

I'm trying to create a simple server that accepts a request, and then writes the content of a file to the browser that sent the request. The server connects and writes to the socket. However my browser says
no data received
and doesn't display anything.
public class Main {
/**
* #param args
*/
public static void main(String[] args) throws IOException{
while(true){
ServerSocket serverSock = new ServerSocket(6789);
Socket sock = serverSock.accept();
System.out.println("connected");
InputStream sis = sock.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(sis));
String request = br.readLine(); // Now you get GET index.html HTTP/1.1`
String[] requestParam = request.split(" ");
String path = requestParam[1];
System.out.println(path);
PrintWriter out = new PrintWriter(sock.getOutputStream(), true);
File file = new File(path);
BufferedReader bfr = null;
String s = "Hi";
if (!file.exists() || !file.isFile()) {
System.out.println("writing not found...");
out.write("HTTP/1.0 200 OK\r\n");
out.write(new Date() + "\r\n");
out.write("Content-Type: text/html");
out.write("Content length: " + s.length() + "\r\n");
out.write(s);
}else{
FileReader fr = new FileReader(file);
bfr = new BufferedReader(fr);
String line;
while ((line = bfr.readLine()) != null) {
out.write(line);
}
}
if(bfr != null){
bfr.close();
}
br.close();
out.close();
serverSock.close();
}
}
}
Your code works for me (data shows up in the browser), if I use
http://localhost:6789/etc/hosts
and there is a file /etc/hosts (Linux filesystem notation).
If the file does not exist, this snippet
out.write("HTTP/1.0 200 OK\r\n");
out.write(new Date() + "\r\n");
out.write("Content-Type: text/html\r\n");
out.write("\r\n");
out.write("File " + file + " not found\r\n");
out.flush();
will return data that shows up in the browser: Note that I have explicitly added a call to flush() here. Make sure that out is flushed in the other case as well.
The other possibility is to reorder your close statements.
A quote from EJP's answer on How to close a socket:
You should close the outermost output stream you have created from the socket. That will flush it.
This is especially the case if the outermost output stream is (another quote from the same source):
a buffered output stream, or a stream wrapped around one. If you don't close that, it won't be flushed.
So out.close() should be called before br.close().

Categories

Resources