I'm communicating Android Device - PC with TCP Sockets. I sent network packets to the server succesfully but when I try to get response from the server, The thread stops I don't know cause.
Android Client :
public class ClientThread implements Runnable
{
public void run()
{
try
{
Socket socket = new Socket("192.168.1.12", 4444);
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
out.write(msg);
out.flush();
Log.v("Naber", "One");
InputStreamReader inputStreamReader = new InputStreamReader(socket.getInputStream());
BufferedReader bufferedReader = new BufferedReader(inputStreamReader); // get the client message
String inMsg = bufferedReader.readLine();
inputStreamReader.close();
Log.v("Naber", "Two");
socket.close();
}
catch (Exception e)
{
Log.v("Hata", e.getMessage());
}
}
}
Log Verbose Output :
09-25 22:25:37.163 15351-15532/com.mytracia.kumanda9 V/Naber﹕ One
I don't know why does it stops when it came to this line :
String inMsg = bufferedReader.readLine();
My Server Application with C#
static void Main(string[] args)
{
TcpListener tcpListener = new TcpListener(IPAddress.Any, 4444);
while (true)
{
tcpListener.Start();
//Program blocks on Accept() until a client connects.
Socket soTcp = tcpListener.AcceptSocket();
Byte[] received = new Byte[1024];
int bytesReceived = soTcp.Receive(received, received.Length, 0);
String dataReceived = System.Text.Encoding.ASCII.GetString(received);
dataReceived = dataReceived.Replace("\0", "");
Console.WriteLine(dataReceived);
String returningString = "Naber1";
Byte[] returningByte = System.Text.Encoding.ASCII.GetBytes(returningString.ToCharArray());
//Returning a confirmation string back to the client.
soTcp.Send(returningByte, returningByte.Length, 0);
tcpListener.Stop();
}
}
Server answer with new line? "\n"
public String readLine () Added in API level 1 Returns the next line
of text available from this reader. A line is represented by zero or
more characters followed by '\n', '\r', "\r\n" or the end of the
reader. The string does not include the newline sequence.
Returns the contents of the line or null if no characters were read
before the end of the reader has been reached.
Try:
String returningString = "Naber1\n";
Related
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.
I'm testing out sockets on my local machine. I'm trying to run both a socket and server in one program using threads. My server is an echo server so that it sends back whatever message it receives. My problem is that when I start both threads, on both the client and server, they 'freeze' when they reach the part where I read from the input stream. It works fine up to the part where the client sends the message. Afterwards, it simply stops as it appears that the client is waiting for a message and so is the server even if I already sent a message to the server via writing to the outputstream. What's wrong with the code?
Client.java
#Override
public void run() {
try {
Socket socket = new Socket("localhost", 22600);
BufferedReader br = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
socket.getOutputStream()));
BufferedReader input = new BufferedReader(new InputStreamReader(
System.in));
System.out.println("Client 1");
while (true) {
System.out.print("\nEnter text : ");
String inputText = input.readLine();
writer.write(inputText);
System.out.println("Client 2");
System.out.println("Client 3");
String s = br.readLine();
System.out.println("CLIENT RECEIVED : " + s);
}
} catch (Exception e) {
e.printStackTrace();
}
}
Server.java
#Override
public void run() {
try {
ServerSocket server = new ServerSocket(22600);
Socket socket = server.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
socket.getOutputStream()));
System.out.println("Server 1");
while (true) {
System.out.println("Server 2");
String s = br.readLine();
System.out.println("Server 3");
if (s == null) {
System.out.println("NULL SERVER SIDE ERROR");
break;
}
writer.write("ECHO : " + s);
System.out.println("SYSOUT ECHO " + s);
}
server.close();
} catch (Exception e) {
e.printStackTrace();
}
}
You are writing a string that does not have an end-of-line at its end.
String inputText = input.readLine();
writer.write(inputText);
System.out.println("Client 2");
The inputText string does not include the end-of-line you typed. And you write it as-is to the server. However, the server tries to read a line:
String s = br.readLine();
System.out.println("Server 3");
So it will keep waiting until the client sends in a newline. But by now the client is waiting for an answer from the server, and now they are deadlocked.
So, you should add a writer.newLine() to the client, as well as the server's echo, which suffers from the same issue. It's also recommended, after each write, to use writer.flush(), on both server and client. Otherwise, it may wait until the buffer is full before actually writing, and the same deadlock will result.
The readLine method of BufferedReader requires a new line terminator to return a value (unless the end of Stream is reached), and then returns the line without this character. So the Client
Reads a line from the user into the variable inputText
Client writes inputText to the OutputStream
Server receives data, but waits until it receives a new line (which it does not).
If you wish to use new line as a delimiter for communication, append this to the end of the data sent
writer.write(inputText + "\n");
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.
Just trying to get a handle on sockets. The server and client are running in two different programs.
They seem to be connecting fine to each other but the client will not properly send its output to the server. The server just hangs. Here's the code:
Server:
private ServerSocket serverSocket;
private Socket client;
public void run() throws Exception {
serverSocket = new ServerSocket(20005);
while(currentState == Game.State.NORMAL) {
client = serverSocket.accept();
PrintWriter out = new PrintWriter(client.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
String clientInput = in.readLine();
// Takes the client input string and does some simple game logic that returns a Gson object
Gson serverResponse = processInput(clientInput);
out.write(serverResponse.toString());
out.flush();
}
}
Client:
Socket clientSocket;
void run() throws Exception {
clientSocket = new Socket("192.168.0.24", 20005);
PrintWriter out;
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
// Print the state of the game - returns false if state is win or lose.
while(printState()) {
out = new PrintWriter(clientSocket.getOutputStream(), true);
// This method just takes some input from the console
String clientInput = getInput();
out.write(clientInput);
out.flush();
String serverResponse = in.readLine();
updateState(serverResponse);
}
}
}
There is some underlying game logic that is happening but it's pretty minor and should be irrelevant. I imagine I am just misunderstanding something fundamental here.
Thanks all.
Make sure you send a newline character to match the in.readLine() statement in the Server.
out.write(clientInput + "\n");
The same applys when sending data from Server->Client.
yes i did look at the tutorials on sun and they didn`t help in my case, only transferred the first command.
I`ve got a method
public void openConnection() throws IOException{
serverSocket = new ServerSocket(5346);
Socket simSocket = serverSocket.accept();
is = simSocket.getInputStream();
os = simSocket.getOutputStream();
writer = new PrintWriter(os);
isReader = new InputStreamReader(is);
reader = new BufferedReader(isReader);
System.out.println("Connection succesfull.");
}
and
public void sendTo(int command) {
try {
writer.println(command);
writer.flush();
} catch(Exception e) {
System.out.println("Error sending command to the robot");
System.out.println(e.toString());
}
}
in the sending side, and
public static void setUpConnection() {
try {
socket = new Socket(InetAddress.getLocalHost(), 5346);
is = new InputStreamReader(
socket.getInputStream());
reader = new BufferedReader(is);
writer = new PrintWriter(socket.getOutputStream());
System.out.println("Simulator: connection succesful");
} catch (IOException e) {
e.printStackTrace();
}
}
and
while (true) {
intCommand = reader.read();
ett = reader.readLine(); // does nothing, but without this line it doesn't work
command = (char) intCommand;
in the receiving side. It works perfectly sending a char or an ascii number of a char. What i need is to change this code to send integers or simply array of bytes instead of a char. if i simply leave just InputStream and OutputStream it does receive the first command and thats it, while these methods continuously receives what is sent through sendTo. Even in sockets documentation they only have exmample with sending chars only.
Just code your server to store the received value as an int instead of a char.