These questions may sound silly, but I am new to this networking thing.
I have been trying for quite a few days now to implement a client that works with a Twisted server, but I am failing to get any response back from the server. I have read a lot of docs and watched a few tutorials and I got some of the stuff fixed and got some of the concepts better understood.
Before I step on to asking any questions, I wanna show you my code first. This is what I use to talk to the Twisted-based server:
val socketfactory: SocketFactory = SocketFactory.getDefault()
val socket = socketfactory.createSocket(host, port)
socket.keepAlive = true
socket.tcpNoDelay = true
val isSocketConnected = socket.isConnected //this checks socket's connectivity
val dOut = DataOutputStream(socket.getOutputStream())
val dIn = DataInputStream(socket.getInputStream())
val teststring = "Hi server!"
dOut.writeUTF(teststring)
Log.d("MILESTONE", "MESSAGE SENT AT THIS POINT, Socket is connected ?: $isSocketConnected")
var testreader = ""
while (true) {
testreader = dIn.readUTF()
Log.d("READING:", "RECEIVED THIS: $testreader")
}
My code seems to never get to the second "Log" line. It never gets there. I assume that's because I never get any input from the server. This is getting me confused. Because "socket.isConnected" returns true. Doesn't that mean there is an ongoing connection between the client (me) and the server ? But when I send any output the server doesn't talk back.
So my questions are:
1- Am I doing something wrong? Why do I receive no talk from the server and it blocks the code?
2- Is SocketFactory necessary ?
3- Is there any library that communicates with Twisted from Java ?
Thanks in advance !
For everyone who's struggling to communicate with a Twisted-running python server, I came with the absolutely best solution ever! After inspecting Twisted's open source code, I came to realize it has a "LineReceiver" class that only responds to a message if the line is finished. In other words, you can keep sending data forever and it will never respond until you finish the line and start a new one. Twisted will know the line has finished when a delimiter is used. (It is configured on the server-side). Most servers running Twisted will use a line delimiter : "\r\n"
That's the tricky thing! Once you send that little string, it will start responding to you. Here it is in an example :
val dOut = DataOutputStream(socket.getOutputStream()) //This is my favorite way of sending data!
val dIn = socket.getInputStream().bufferedReader(Charsets.UTF_8) //This is my favorite way of reading data !
val teststring = "hi server! \r\n" //This is the tricky part !
That's it ! all you have to do after that is read the lines from the bufferedReader, like this !
var testreader: List<String>
while (true) {
testreader = dIn.bufferedReader(Charsets.UTF_8).readLines()
for (line in testreader)
Log.e("MILESTONE", line)
}
After I started reading the input, I found out the server started actually sending me strings and communicating back with me. I hope everyone will get their codes working concerning this or any other thing!
Related
I'm very new to networking in java and wanted to create a network chat program, I have found a few tutorials online and kind of drifted from that. I have the server of my program working and the only thing that is interfering is when I try to read the chat messages that the server sends over. The server does send the bytes of data over since the print message does work. So the problem is that the while loop never ends, what can this be a problem of?
public String[] updateChatDialog() throws IOException{
String returnString = "";
int accessed = -1;
while((accessed = in.read()) > 0){
System.out.println((char)accessed);
returnString = returnString + (char)accessed;
}
System.out.println(returnString);
return stringToTable(returnString);
}
Any tips on java networking would be helpful!
I do reset the BufferedInputStream every time the chats are rendered into a string, AKA the method above with the return in it.
The 'problem' is that your loop reads until end of stream, and the peer isn't closing the connection so EOS never arrives.
If you want to read messages you have to define them yourself. The easiest thing for you to do in this application is write and read lines, with e.g. PrintWriter.println() and BufferedReader.readLine().
I have followed Google's tutorial on using Bluetooth on Android. On the server side which is a computer I've used Bluecove.
I have managed to establish the connection between the devices (they weren't paired first and when I ran the program both of the devices asked to accept the pairing). Now I have problem with sending data over the connection. In the Managing a connection section there's a method called write. With that function I'm not able to send anything. It doesn't fail (no errors) but the message doesn't reach the server.
On the server after accepting the connection (acceptAndConnect()) I have the following
DataInputStream inputStream = new DataInputStream(connection.openInputStream());
while(true) {
String input = "";
char c;
while(((c = inputStream.readChar()) > 0) && (c != '\n')) {
input += c;
}
System.out.println("Received: " + input);
}
It doesn't print anything.
The code on the client side is exactly the same as in the tutorial. Where is the problem?
Edit. Actually, if I print c in the server code shown up I get something strange. I've tried to send hello\n. When printing c, I get 桥
汬
漊
After a little bit of more googleing I found Jon Skeet's answer and changed the DataInputStream to an InputStream wrapped in an InputStreamReader and that one in a BufferedReader. Then I can use readLine() and I get the characters right.
I currently have a problem with a Java server thingy.
It's a simple TCP server which send images. Problem is, I don't have the code of the client program... Moreover, it seems that there is no way to check the client socket for writing event nor the amount of data already sent to the client.
Do someone have any idea about what could prevent the client to get the image correctly ?
Here's my code :
byte[] response = process ( cmd );
if ( response == null )
{
controlSock.close();
dataSock.close();
stop = true;
}
else if ( dataSock != null )
{
dos.write( response );
dos.flush();
}
By the way, the server is working fine with Telnet.
If the server works fine with telnet then your server is fine.
The problem is more likely to be in the assumptions the client is making are not the same as yours. for example the client might assume you are sending the size first in big or little endian format (as an int, short or long) Perhaps it expects the name of the file/image in some format as well.
The only way to know this for sure is to read the code for the client or ask someone who knows what assumptions the client makes.
I want to connect to a number of different sockets/webservices on the command line and send data back and forth in the standard output/input.
I have been doing this using a variety of different languages and approaches so far: System.Net.Sockets in C#, flash.net.sockets in Flash and java.net.sockets in Java, depending on the protocol being used by the socket and the language being used in the client example given by the companies who've written the sockets. I've had enough of moving from language to language to do this (using the provided client socket example in each case), and will probably all the clients to java.
In the meantime, I want a way to connect to a socket on the command line in windows, see what's return in the standard output, send text to the socket on the command line (or a very, very simple GUI) and see what's returned back. I don't need any extra functionality like a periodic ping to keep the socket alive or anything.
What tools can I do this on Windows with? I've tried opening a telnet session to the socket i.e. push.domain.com 1234, and also tried using Putty to connect also, to no avail.
I'm trying to emulate the way a flash client connects to this socket and sends and receives data:
theSocket.addEventListener(Event.CONNECT, connectHandler);
theSocket.connect(theHost, thePort);
* * *
private function connectHandler(event:Event) : void
{
if (theSocket.connected)
{
bytes = new ByteArray();
bytes.writeByte(35);
bytes.writeByte(1);
bytes.writeByte(23);
bytes.writeByte(7);
bytes.writeUTFBytes(theTopic);
bytes.writeByte(0);
theSocket.writeBytes(bytes);
theSocket.flush();
theSocket.addEventListener(ProgressEvent.SOCKET_DATA, handshakeHandler);
* * *
private function handshakeHandler(event:ProgressEvent) : void
{
var zero:int = 0;
theSocket.removeEventListener(ProgressEvent.SOCKET_DATA, handshakeHandler);
theConnectionTimer.stop();
var bytes:* = new ByteArray();
var counter:int = 0;
theSocket.readUTFBytes(theSocket.bytesAvailable));
var a:* = theSocket.readByte();
var b:* = theSocket.readByte(); // the second byte should be 1????
var response:* = theSocket.readByte(); // this is the reponse identifier. . . ???
theMessageSize = theSocket.readByte(); // is this byte the size??????
switch(response)
{
case 100:
{
while ((zero = theSocket.readByte()) != 0)
{
var temp = counter++;
bytes[temp] = _loc_5;
};
theClientID = bytes.toString();
trace("The client ID is: " + theClientID);
How can I send the bytes values of 35, 1, 23, 7 and 0, as well as the value of the variable, Topic, to the socket using Hercules (or any other tool). Ideally, I'd like to connect with Hercules, send those bytes and the topic, and get something back containing the clientID like in the code. Although, I don't know if hercules will render the bytes in the response into text for me.
I'd appreciate any pointers at all on this.
Thanks.
I was thinking in Hercules and searching for the website I found out that there's already an answer here in stackoverflow.
I think it does what you need and more.
Uhm, I'm nost sure I understood completely what you are asking, but I don't see why telnet could not help you in this case.
i'm developing a simple test to connect via socket a java server application with an objective-c client side.
This is the java side:
BufferedReader dis = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String message = dis.readLine();
System.out.println("Message Received: " + message);
dis.close();
socket.close();
This is the objective-c side:
- (IBAction)click:(id)sender{
#try {
[socket sendString:[NSString stringWithFormat:#"%#",[toSend text]]];
}
#catch (NSException * e) {
NSLog(#"Unable to send data");
}
[toSend resignFirstResponder];
}
There are many problems:
in this way the output of server is:
Message Received: null
i read on this that readLine() needs to receive a string with "\n" that ends string, so i edit the line upon adding \n:
[socket sendString:[NSString stringWithFormat:#"%#\n",[toSend text]]];
but i retrieve an error on this line: EXC_BAD_ACCESS like in screenshot
What could be the problem? can someone help me?
I made a prototype in the Java side, and I don't have Objective-C/iOS or an Apple product.
I suspect the problem could be either in iOS or the Java side. So I hope you're sending text from iOS correctly.
Proposed code:
BufferedReader dis = new BufferedReader(new InputStreamReader(socket.getInputStream(), Charset.defaultCharset()));
The class InputStreamReader need a defined character set. The charset is supposed to be required, not optional! according to Sun documentation.
For expediency, pls just include more code for clean compile next time. Thanks.
Good luck n try it out!
Tommy Kwee
According to your modified post/question, you got an exception from the Objective-C side. So possibly the problem is not on the Java side.
For debugging purposes, I am proposing to make the C code simpler, like...
BOOL success;
success = [socket SendString: #"Hello World!"];
if (success != YES) {
NSLog(#"Fail to send")
}
Notes:
I am not familiar with Objective-C, and I could not find documentation from Apple on it. If you know, please tell me/us.
I did not use code "[toSend text]" because I did not find any references on it.
Other iOS developers are saying "%#" is meant for objects. Is code [toSend text] an object?
Finally, making a socket connection and achieving communication should be possible and not so hard, and eventually we'll get there. So let's do it!