i created a sever socket program to send a stream data to Apache spark.But data is received by spark after i close the socket or termination of program.i need to send data without closing socket and terminating program.
import java.io.DataOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class SocketServer {
public static void main(String[] args) {
try {
ServerSocket ss = new ServerSocket(9999);
Socket s = ss.accept();// establishes connection
DataOutputStream dout = new DataOutputStream(s.getOutputStream());
Scanner scanner = new Scanner(System.in);
String s1 = "";
while (!s1.equals("end")) {
s1 = scanner.next();
dout.writeUTF(s1);
dout.flush();
}
ss.close();
} catch (Exception e) {r
System.out.println(e);
}
}
}
i can send data in stream using nc server nc -lk 9999.
EDIT -1 Tried with println
try {
ServerSocket ss = new ServerSocket(6000);
Socket s = ss.accept();// establishes connection
OutputStream ostream = s.getOutputStream();
PrintWriter pwrite = new PrintWriter(ostream, true);
Scanner scanner = new Scanner(System.in);
String s1 = "";
while (!s1.equals("end")) {
s1 = scanner.next();
pwrite.println(s1);
pwrite.flush();
}
ss.close();
} catch (Exception e) {
System.out.println(e);
}
Still not working.
Please help..
Unless Apache Spark is (a) written in Java and (b) calling readUTF() you're using the wrong method to send. You should probably be using a println() method. You also need to close the accepted socket, as well as the server socket.
First of all you should only be instantiating dout once (before the start of the while loop).
Secondly I believe the way it works is that when reading from a socket stream it reads until the end of the stream is reached (ie socket is closed). To finish reading early you'd need to send an "end of stream" without closing it.
Related
I am trying to combine Python and Java using a socket connection. I hava a Java server and a Python client. They are able to connect to each other, and the server is able to write to the client, but when I try to send a message from the client to the server, it throws an EOFException. What should I do to get this to work?
Server code:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) {
try {
ServerSocket serversocket = new ServerSocket(6000);
Socket client = serversocket.accept();
final DataInputStream input = new DataInputStream(client.getInputStream());
final DataOutputStream output = new DataOutputStream(client.getOutputStream());
output.writeUTF("Hello Client!");
String message = (String)input.readUTF();
System.out.println(message);
serversocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Client code:
import socket
socket = socket.socket()
host = "localhost"
port = 6000
socket.connect((host, port))
message = socket.recv(1024)
print(message.decode())
socket.sendall("Hello Server".encode())
socket.close()
The exception:
java.io.EOFException
at java.base/java.io.DataInputStream.readFully(DataInputStream.java:203)
at java.base/java.io.DataInputStream.readUTF(DataInputStream.java:615)
at java.base/java.io.DataInputStream.readUTF(DataInputStream.java:570)
at Server.main(Server.java:19)
Option #1:
Replace input.readUTF() in server with this:
while(true) {
int ch = input.read();
if (ch == -1) break;
System.out.print((char)ch);
}
Option #2:
If want to read UTF-encoded strings (vs plain ASCII) on server then recommend using BufferedReader with utf-8 charset and readLine().
ServerSocket serversocket = new ServerSocket(6000);
System.out.println("Waiting for connections");
Socket client = serversocket.accept();
final BufferedReader input = new BufferedReader(
new InputStreamReader(client.getInputStream(), StandardCharsets.UTF_8)); // changed
final OutputStream output = client.getOutputStream();
//output.writeUTF("Hello Client!"); // see note below
output.write("Hello Client!".getBytes(StandardCharsets.UTF_8)) // changed
String message = input.readLine(); // changed
System.out.println(message);
client.close();
serversocket.close();
Client output:
Hello Client!
Server output:
Hello Server
Note JavaDoc of DataOutputStream#writeUTF(...) says:
First, two bytes are written to the output stream as if by the
writeShort method giving the number of bytes to follow.
Using output.write(s.getBytes(StandardCharsets.UTF_8)) is more compatible with non-Java clients. Python utf-8 decoding doesn't support the 2-byte length prefix added by writeUTF().
Finally, if want the server to handle more than one client connection, then add a loop that encloses the code after ServerSocket is created and only close the client socket inside the loop.
I've just started with both java and networking with servers and clients. Although i understand the basics of whats going on, i was struggling to put it all together and do what i wanted to do in the title.
I was able to make this to send a message to the server, however i was wondering how i'd turn the message into a input string from the user, and also how id send multiple messages between the client and server
thanks
SERVER
import java.io.*;
import java.net.*;
public class Server {
//Main Method:- called when running the class file.
public static void main(String[] args){
//Portnumber:- number of the port we wish to connect on.
int portNumber = 15882;
try{
//Setup the socket for communication and accept incoming communication
ServerSocket serverSoc = new ServerSocket(portNumber);
Socket soc = serverSoc.accept();
//Catch the incoming data in a data stream, read a line and output it to the console
DataInputStream dataIn = new DataInputStream(soc.getInputStream());
System.out.println("--> " + dataIn.readUTF());
//Remember to close the socket once we have finished with it.
soc.close();
}
catch (Exception except){
//Exception thrown (except) when something went wrong, pushing message to the console
System.out.println("Error --> " + except.getMessage());
}
}}
CLIENT
import java.io.*;
import java.net.*;
public class Client {
//Main Method:- called when running the class file.
public static void main(String[] args){
//Portnumber:- number of the port we wish to connect on.
int portNumber = 15882;
//ServerIP:- IP address of the server.
String serverIP = "localhost";
try{
//Create a new socket for communication
Socket soc = new Socket(serverIP,portNumber);
//Create the outputstream to send data through
DataOutputStream dataOut = new DataOutputStream(soc.getOutputStream());
//Write message to output stream and send through socket
dataOut.writeUTF("Hello other world!");
dataOut.flush();
//close the data stream and socket
dataOut.close();
soc.close();
}
catch (Exception except){
//Exception thrown (except) when something went wrong, pushing message to the console
System.out.println("Error --> " + except.getMessage());
}
}}
There are some "problems" with your code.
You should only close the ServerSocket if you are done.
You should handle the newly connected client inside a thread to allow multiple clients to simultaniously "send messages".
1.
you could easily wrap your code inside an while loop.
boolean someCondition = true;
try{
//Setup the socket for communication and accept incoming communication
ServerSocket serverSoc = new ServerSocket(portNumber);
// repeat the whole process over and over again.
while(someCondition) {
Socket soc = serverSoc.accept();
//Catch the incoming data in a data stream, read a line and output it to the console
DataInputStream dataIn = new DataInputStream(soc.getInputStream());
System.out.println("--> " + dataIn.readUTF());
}
//Remember to close the socket once we have finished with it.
soc.close();
}
Now your programm should continue to accept clients. But only one at a time. You can now terminate the Server by stopping the programm or by changing the someCondition to false and accepting the next client.
A bit more advanced would be, to shutdown the ServerSocket to stop the programm and catching the exception inside the while loop.
2.
To allow multiple clients to be handled simultaniously, you should pack the handle part into another Thread.
private ExecutorService threadPool = Executors.newCachedThreadPool();
boolean someCondition = true;
try{
//Setup the socket for communication and accept incoming communication
ServerSocket serverSoc = new ServerSocket(portNumber);
// repeat the whole process over and over again.
while(someCondition) {
Socket soc = serverSoc.accept();
//Catch the incoming data in a data stream, read a line and output it to the console in a new Thread.
threadPool.submit(() -> {
DataInputStream dataIn = new
DataInputStream(soc.getInputStream());
System.out.println("--> " + dataIn.readUTF());
}
}
//Remember to close the socket once we have finished with it.
soc.close();
}
The part inside the threadPool.submit block could be specified as an custom instance of the Runnable interface of as an method, to call it using method reference.
I assumed you are knowing about ThreadPools. They have multiple advantages over Threads
This should get you going for any number of clients.
Note: This is not good designed, but it is for demonstrational porpurses only.
i have a socket in client that connects to an server to send and receive String, uses writeUTF() and readUTF() to read and write to socket, when i write a string from client to socket and read them on server then it's work. But when server receive string from socket and write "flag" to socket to read them on client then client hang at read line. Here is my code.
Server
public void run(){
DataInputStream input = null;
try{
output = new DataOutputStream(socket.getOutputStream());
input = new DataInputStream(socket.getInputStream());
while((true)&&(this.active)){
String receive = input.readUTF();
String[] str = receive.split("#");
if (str[0].equals("get_list")){
output.writeUTF("flag");
}
}
}catch(IOException ex){
}
Client
public void run(){
DataOutputStream output = null;
try{
output = new DataOutputStream(socket.getOutputStream());
DataInputStream input = new DataInputStream(socket.getInputStream());
output.writeUTF("get_list#");
String receive = input.readUTF(); //Hang at this line
System.out.println(receive);
} catch (IOException ex) {
}
So I'm having some serious problems with Java's server side socket, which accepts connection, but it can't read anything from BufferedReader, which I have put to read the text stream from socket connection. Code for my threads run(), which I'm creating and running at the first time when any page is loaded.
public void run() {
try{
ServerSocket s = new ServerSocket(4100);
System.out.println("New tcp socket created");
Socket socket = s.accept();
System.out.println("New tcp update connection established.");
InputStream din = socket.getInputStream();
PrintWriter outp = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(din));
System.out.println("Streams created");
String inputline = "nothing yet...";
outp.println("hello from server");
while(true){
System.out.println("Got input from client:" + inputline);
inputline = in.readLine();
if(inputline == null || inputline.equals("exit")){
break;
}
}
}
catch(Exception e){
e.printStackTrace();
}
System.out.println("Updater thread exits.");
}
This prints out everything properly, except for Got input from client: + what ever my client sends with PrintWriter which outputs to a socket.
Client side example:
Socket s = new Socket(serverip, serverDownloadsUpdatePort);
OutputStream dout = s.getOutputStream();
PrintWriter outp = new PrintWriter(dout);
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
System.out.println(in.readLine());//This prints out properly, what server sends to client
outp.println("test connection");
outp.println("Can you hear me?");
outp.println("exit");
s.close();
Your client may not be sending end-of-line characters along with its input, causing your server to wait indefinitely at "in.readLine()".
The Javadoc for BufferedReader's readLine method (http://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html#readLine()) says: "Reads a line of text. A line is considered to be terminated by any one of a line feed ('\n'), a carriage return ('\r'), or a carriage return followed immediately by a linefeed." Make sure that your client is sending input that conforms to this rule.
I was able to see client input using your server with the following client Runnable (but only if I include the "\n"):
public void run() {
try{
Socket writeSocket = new Socket("localhost", 4100);
PrintWriter out =
new PrintWriter(writeSocket.getOutputStream(), true);
out.write("Hello there!\n");
out.flush();
}
catch(Exception e){
e.printStackTrace();
}
}
EDIT: When using println as in the submitter's client example, you don't need to worry about adding "\n", but you do need to flush the socket. One way to make sure this happens is by setting autoFlush=true in the PrintWriter constructor.
I found out that I forgot to set PrintWriter as auto flushable at client side and thats why it didn't work becouse stream didn't got flushed at any time.
I'm building a Java client application which needs to send a message to a server and receive a response afterwards. I can send the message successfully, the problem is that I can't get the response because I get an IO exception ("Socked is closed") when trying to read the 'BufferedReader'.
This is my code, so far:
public class MyClass {
/**
* #param args the command line arguments
*/
#SuppressWarnings("empty-statement")
public static void main(String[] args) {
JSONObject j = new JSONObject();
try {
j.put("comando", 1);
j.put("versao", 1);
j.put("senha", "c4ca4238a0b923820dcc509a6f75849b");
j.put("usuario", "1");
j.put("deviceId", "1");
} catch (JSONException ex) {
System.out.println("JSON Exception reached");
}
String LoginString = "{comando':1,'versao':1,'senha':'c4ca4238a0b923820dcc509a6f75849b','usuario':'1','deviceId':'1'}";
try {
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
Socket clientSocket = new Socket("10.1.1.12", 3333);
System.out.println("Connected to the server successfully");
PrintWriter outToServer = new PrintWriter(clientSocket.getOutputStream(),true);
outToServer.println(j.toString());
outToServer.close();
System.out.println("TO SERVER: " + j.toString());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String resposta = inFromServer.readLine();
System.out.println("FROM SERVER: " + resposta);
clientSocket.close();
} catch (UnknownHostException ex) {
System.out.println("Could not connect to the server [Unknown exception]");
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
}
I know that the socket is being closed because of the OutToServer.close() but closing the stream is the only way to send the message. How should I approach this situation?
flush() is not the case when it comes with new PrintWriter(, true).
The real problem is that you are closing the PrintWriter outToServer which wraps the underlying InputStream, again, came from the Socket.
When you close the outToServer you're closing the whole socket.
You have to use Socket#shutdownOutput().
You don't even have to close the output if you want to keep the socket's in/out channels for further communications.
flush() when you are done with any writeXXX. Those writeXXX practically don't mean you sent those bytes and characters to other side of the socket.
You may have to close the output, and output only, to signal the server that you sent all you had to send. This is really a matter of the server-side socket's desire.
final Socket socket = new Socket(...);
try {
final PrintStream out = new PrintStream(socket.getOutputStream());
// write here
out.flush(); // this is important.
socket.shutdownOutput(); // half closing
// socket is still alive
// read input here
} finally {
socket.close();
}
Try to call outToServer.flush()
That will try to flush the data from the buffer, although it still not guarantees that it will be sent.