Ascii on TCP socket - java

Anyone could pass me an example of sending Ascii msg over TCP?(couldnt find example on the net)
thanks,
ray.

Here's an example of writing to and reading from an echoing server.
A simplified excerpt:
Socket echoSocket = null;
PrintWriter out = null;
BufferedReader in = null;
try {
echoSocket = new Socket("taranis", 7);
out = new PrintWriter(echoSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(
echoSocket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Don't know about host: taranis.");
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for "
+ "the connection to: taranis.");
System.exit(1);
}
BufferedReader stdIn = new BufferedReader(
new InputStreamReader(System.in));
String userInput;
while ((userInput = stdIn.readLine()) != null) {
out.println(userInput);
System.out.println("echo: " + in.readLine());
}

Not sure, I think this should work:
try (DataOutputStream outToClient = new DataOutputStream(socket.getOutputStream())) {
outToClient.write(stringMessage.getBytes("US-ASCII"));
} catch (IOException e) {}

Not stated in the original question is whether ASCII control codes have to handled.
While the accepted answer works for printable ASCII characters I've had problems (on Windows 7 Enterprise SP1) using it for strings containing ASCII control codes, especially strings containing any of the java newline "characters", e.g. VT, CR, LF, etc. A workaround is to send the string as bytes and convert it back to a string at the far end.
See my answer to this question for how to handle that situation.
Reading Lines and byte[] from input stream
and my closely related question and it's accepted answer:
Need TCPIP client that blocks until a specific character sequence is received

Related

BufferedReader in Socket Programming

When i am trying to send an input from a client, if i don't concat "\r\n" at the end of the string, my inputstream waits forever. I have seen various similar posts but couldn't find a proper solution. My code is as follows:
public void run() {
PrintWriter out = null;
BufferedReader in = null;
try {
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String line;
if (in.ready()) {
if ((line = in.readLine()) != null) {
System.out.println("Received from client: " + line);
out.write("Echoing: " + line);
out.flush();
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
out.close();
try {
in.close();
clientSocket.close();
System.out.println("Closing connection from " + socketAddress + ", #" + connectionId);
} catch (IOException e) {
e.printStackTrace();
}
}
}
If you only want to read some of the data that was sent, use the read(char[]) method instead of the readLine method. This method returns the number of characters it read as an int. Example:
char[] buffer = new char[2000];
int read;
if ((read = in.read(buffer)) != -1) {
String line = new String(buffer, 0, read);
System.out.println("Received from client: " + line);
out.write("Echoing: " + line);
out.flush();
}
What you'll see happen next is that this code sometimes fails to read the entire message you send from PHP, or that two or more messages are read as one.
If you want to fix that:
This will never work, and it's not because of PHP or Java. You're using TCP, a stream oriented protocol. There is no guarantee that the message you write to the socket from the PHP program will arrive in one piece to the receiver. The message may be broken up and you need multiple socket function calls to read it. Or it may go the other direction, and a single call to read returns more than one message.
The solution is to add some kind of framing for the messages so that the receiver knows when it has a complete message. Always ending a message with a line break serves as framing, if messages themselves are single lines. Another solution is to ditch TCP and use a message oriented protocol (like UDP) instead, but that will come with its own complications.

Java: client socket does not read the second line and remains open after the terminator line

Having read tens of examples online, I am still stuck with the problem.
I am sending a message from my client in Java to a server in C++. After receiving the hand-shake message, the server sends back the following data:
"0000:1111:2222:3333:4444
END_CONNECT_DATA"
As soon as the last line (terminator) is read by the client, it should close the connection.
This is how I do it:
Socket socket = null;
String terminator = "END_CONNECT_DATA";
try
{
int serverPort = 7767;
String ip = "192.168.1.10";
String messageOut = "HAND-SHAKE MESSAGE";
socket = new Socket(ip, serverPort);
DataInputStream input = new DataInputStream( socket.getInputStream());
DataOutputStream output = new DataOutputStream( socket.getOutputStream());
//Send message
output.writeBytes(messageOut);
//Read Response
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
StringBuffer sb = new StringBuffer();
String s = "";
while((s = br.readLine()) != null)
{
System.out.println("CHECK !!!");
System.out.println(s);
sb.append(s);
if(s.contains(terminator))
{
System.out.println("CHECK TERMINATOR");
break;
}
}
socket.close();
String data = sb.toString();
System.out.println("FULL DATA:\n");
System.out.println(data);
}
catch (UnknownHostException e)
{
System.out.println("Sock:"+e.getMessage());
}
catch (EOFException e)
{
System.out.println("EOF:"+e.getMessage());
}
catch (IOException e)
{
System.out.println("IO:"+e.getMessage());
}
finally
{
if(socket!=null)
{
try
{
socket.close();
}
catch (IOException e)
{
}
}
}
}
What I get back from the server is only the first line. The cursor goes to the next line and continues blinking. The socket connection is not closed. Looks like the client is not reading the terminator (the second line of the message) at all.
Any ideas?
Thanks a lot!
As documented, the loop fails to read in the second line as it's not terminated with \r or \n. Therefore, returning only the result up till then, which is the first line as described.
You'll need to either add in a \r or \n right after the terminator or use BufferedReader.read() instead and check manually or adopt another strategy to read in the message
Clearly the peer is neither sending a line terminator after the last line nor closing the socket. Ergo using readLine() to read those messages is not correct. If you can adjust the peer, do so.

Having trouble sending String from client socket to server socket, and vice versa

I am trying to create an application that will count the amount of times a button has been clicked. This client would connect to a server, and when the user clicks the button, it should increment the counter on the server. The server should then send back the current amount of clicks to the client. But that's where I'm having a bit of problems.
This is the relevant client-sided code.
public void actionPerformed(ActionEvent arg0) {
try {
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
String target = "";
bw.write("increment" + "\n");
bw.flush();
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String id = br.readLine();
System.out.println("test: " + id);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
The client stops at:
String id = br.readLine();
I just want to get the output from the server.
This is the relevant server-sided code.
public void run() {
try {
while (true) {
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is); //Create the input Streams
BufferedReader br = new BufferedReader(isr);
String input = br.readLine();
System.out.println("got input");
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
System.out.println("wrote to out");
if(input.equals("increment" + "\n")) {
totalBets++;
System.out.println("inif");
bw.write(totalBets);
System.out.println("wrote");
bw.flush();
System.out.println("flushed");
System.out.println("Total Bets: " + totalBets);
}
}
} catch (IOException e) {
log("Error handling client# " + clientNumber + ": " + e);
} finally {
try {
socket.close();
} catch (IOException e) {
log("Couldn't close a socket, what's going on?");
}
log("Connection with client# " + clientNumber + " closed");
}
}
I found that it also stops here:
String input = br.readLine();
I'm just trying to get the bw.write("imcrement") from the client, so the server can increment the counter, and send back the total clicks.
Any help?
Thank you.
You are writing the totalBets value using BufferedWriter.write(int).
This interprets the value as a single character. So, for example, if totalBets is 65, it writes the character 'A'!
Moreover, it does not add a newline. So the client reads that 'A' but tries to read more characters as it is trying to read a whole line. Remember that you have to write lines to read lines.
Thus, you should replace the part that writes totalBets with:
bw.write(String.valueOf(totalBets));
bw.newLine();
Also remember, as I pointed in a comment, that you have to write a line with a \n (or preferably BufferedWriter.newLine()), but when you read the line on the other side, the line separator is stripped away, so you should compare the string you expect without a \n.
You need to set TCP_NODELAY on the client's socket. The default is for data to be buffered until it will fill an entire packet. When the buffer is full, a packet is sent. However, for this protocol you want the data to be sent immediately so that the server can respond.
I frequently use wireshark when testing and debugging my networking code. It will show exactly what packets are sent and received. (note, however, that on Windows you can not capture from the loopback interface; this is a limitation of Windows and does not apply to other systems)

Java socket timing out: Broken pipe

I'm writing a simple server in Java, and I'm able to retrieve incoming data from the client on the server side, but not on the client side due to a 2000ms timeout. Anyone know why this times out?
This is the server's code:
private static void listen() throws IOException {
while(true) {
Socket clientSocket = serverSocket.accept();
StringBuilder bufferedStringInput = new StringBuilder();
CharBuffer cbuf = CharBuffer.allocate(4096);
try {
InputStream is = clientSocket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF8"));
int noCharsLeft = 0;
while ((noCharsLeft = br.read(cbuf)) != -1) {
char[] arr = new char[noCharsLeft];
cbuf.rewind();
cbuf.get(arr);
bufferedStringInput.append(arr);
cbuf.clear();
}
System.out.println(bufferedStringInput.toString());
} catch (IOException e) {
System.out.println("Error received client data: " + e.getMessage());
}
String message = "Hello client";
try {
PrintWriter out = new PrintWriter(clientSocket.getOutputStream());
out.print(message);
} catch (IOException e) {
System.out.println("Error getting output stream from client: " + e.getMessage());
}
clientSocket.close();
}
}
You're reading the input until end of stream, which only happens when the peer closes the connection, then you're trying to write to it, so of course you get a broken pipe. Doesn't make sense. You should just read the input until you have one entire request, whatever that means in your protocol.
There are other problems lurking here:
If the client code uses readLine(), you're not sending a line terminator: use println(), not print(), and close the PrintWriter, not just the client socket.
cbuf.rewind()/get()/clear() should be cbuf.flip()/get()/compact().
But it would make more sense to read directly into a char[] cbuf = new char[8192]; array, then bufferedStringInput.append(cbuf, 0, noCharsLeft), and forget about the CharBuffer altogether. Too much data copying at present.
noCharsLeft is a poor name for that variable. It is a read count.

Timeout on a java util scanner?

I have the following problem, I have a simple TCP class in my application that sends a message off to a device for a query, the device then responds with the message however there is no end of line character of any description because it is coming from a serial converter, after initially atempting to use the readline function and discovering it requires the eol character before outputting I have tried the scanner function which works fine unless the device doesnt reply to that request for some reason, my application then freezes, is it possible to set a timeout on the scanner function so that it then drops the connection and moves on or is there a better way to do this? my code is below:
public String Send_TCP ( InetAddress IPAddress, int POrt, String InData) throws IOException
{
Socket socket = null;
PrintWriter out = null;
BufferedReader in = null;
try {
socket = new Socket(IPAddress, POrt);
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Don't know about host");
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection");
System.exit(1);
}
BufferedReader read = new BufferedReader(new InputStreamReader(System.in));
;
System.out.print("Connected, Sending:"+ InData);
out.println(InData);
System.out.println("Equals");
String str1 = new Scanner(in).useDelimiter(">").next() + ">";
System.out.println(str1);
System.out.println("Equals");
out.close();
in.close();
read.close();
socket.close();
return str1;
}
}
I'm not sure that I understand your question correctly but you can set a timeout on the socket: socket.setSoTimeout(int timeout).
See: javadoc
I believe the following achieves what I need it to, basically checking if the buffer exists, if it doesnt then it waits and checks again avoiding the trap of the scanner function if the message never arrives if it does it reads it.
try {
BufferedReader rd = new BufferedReader(new InputStreamReader(sock.getInputStream()));
int count = 1;
do {
if (rd.ready()){
System.out.println ("Response Ready");
str = new Scanner(rd).useDelimiter(">").next()+">";
count = 501;
}
Thread.sleep(10);
System.out.println ("Response Not Ready" + count);
count ++;
} while (count < 25);

Categories

Resources