i'm new to programming and I'm trying to build a blackberry IRC Client, I made it connect to a server, join a channel and say something, but how can I receive messages ? I don't know how to make a loop to wait for messages, can somebody help me ? here is my code:
package com.rim.samples.device.socketdemo;
import java.io.*;
import javax.microedition.io.*;
import net.rim.device.api.ui.*;
public class ConnectThread extends Thread
{
private InputStream _in;
private OutputStreamWriter _out;
private SocketDemoScreen _screen;
// Constructor
public ConnectThread()
{
_screen = ((SocketDemo)UiApplication.getUiApplication()).getScreen();
}
public void run()
{
StreamConnection connection = null;
String user = "Cegooow";
String channel = "#oi";
try
{
_screen.updateDisplay("Opening Connection...");
String url = "socket://" + _screen.getHostFieldText() + ":6667" + (_screen.isDirectTCP() ? ";deviceside=true" : "");
connection = (StreamConnection)Connector.open(url);
_screen.updateDisplay("Connection open");
_in = connection.openInputStream();
_out = new OutputStreamWriter(connection.openOutputStream());
StringBuffer s = new StringBuffer();
_out.write("NICK " + _screen.getNickText() + "\r\n");
_out.write("USER " + user + "8 * : Java Bot\r\n");
_out.write("JOIN " + channel + "\r\n");
_out.write("PRIVMSG " + channel + " " + _screen.getMessageFieldText() + "\r\n");
_screen.updateDisplay("Done!");
}
catch(IOException e)
{
System.err.println(e.toString());
}
finally
{
_screen.setThreadRunning(false);
try
{
_in.close();
}
catch(IOException ioe)
{
}
try
{
_out.close();
}
catch(IOException ioe)
{
}
try
{
connection.close();
}
catch(IOException ioe)
{
}
}
}
}
I used the sockets demo sample on blackerry jre, thanks
In your code you have an OutputStreamWriter _out to write to the Server, the incoming connection _in (InputStream) is unused. You should expect any incoming data there...
The simplest example I can think of would be like this:
// process the inputstream after writing to _out - in single threaded app
Reader reader = new InputStreamReader(_in);
int data;
while((data = reader.read()) != -1 ){
System.out.println((char) data); // do something with the char
}
reader.close();
In practice, it would be better to use a BufferedReader. Also, if you are building a chat application it might be beneficial to create a new thread to process incoming data and another thread for outgoing data.
Once you get your input stream reader handle you can loop until connection closes
BufferedReader reader = new BufferedReader(_in);
while(true) {
String line = reader.readLine();
// do something...
}
Related
I am using this codes in communicating with Evolis KC200 printer:
#Test
public void studyPipe() {
try {
String echoText = " {\"id\":\"1\",\"jsonrpc\":\"2.0\",\"method\":\"CMD.GetStatus\",\"params\":{\"device\":\"Evolis KC200\"}}";
System.out.println("CMD.GetStatus Request: " + echoText);
String pipeName = "\\\\.\\pipe\\EspfServer00";
RandomAccessFile pipe = new RandomAccessFile(pipeName, "rw");
System.out.println("Writing in pipe: " + echoText + " in pipe "
+ pipeName);
pipe.write(echoText.getBytes("UTF-8"));
// Thread.sleep(1000);
String echoResponse = pipe.readLine();
System.out.println("Response: " + echoResponse);
pipe.close();
} catch (Exception e) {
e.printStackTrace();
}
}
But all I'm getting is this:
java.io.IOException: No process is on the other end of the pipe
at java.io.RandomAccessFile.read0(Native Method)
at java.io.RandomAccessFile.read(RandomAccessFile.java:330)
at java.io.RandomAccessFile.readLine(RandomAccessFile.java:939)
at
They have a test tool built on another language (C#) and their Named Pipe client looks like this:
What is missing in my JAVA codes?
public static string SendRequestPipe(string ip, string port, string request)
{
NamedPipeClientStream objPipeClient;
string answer = string.Empty;
objPipeClient = new NamedPipeClientStream(ip, port, PipeDirection.InOut);
try
{
// Connexion au named pipe ou attente de la disponibilité du named pipe
objPipeClient.Connect(1000);
// Paramétrage de la connexion
objPipeClient.ReadMode = PipeTransmissionMode.Message;
if (objPipeClient.IsConnected == true)
{
// Send request
byte[] datain = Encoding.UTF8.GetBytes(request);
objPipeClient.Write(datain, 0, datain.Length);
// Get answer
int recv = 0;
byte[] data = new byte[1024];
do
{
recv = objPipeClient.Read(data, 0, data.Length);
answer += Encoding.UTF8.GetString(data, 0, recv);
} while (!objPipeClient.IsMessageComplete);
}
}
catch (Exception ex)
{
}
finally
{
objPipeClient.Close();
objPipeClient.Dispose();
}
return answer;
}
I also tried similar approaches in Java but I'm getting the same error.
UPDATE:
I think I know the issue already but I still do not have the resolution.
It seems that the JAVA code is creating another instance of the PIPE that is why it is not receiving any process on that new instance.
I tested with the C# code and it was not creating a new instance.
I checked the instances using this tool:
https://learn.microsoft.com/en-us/sysinternals/downloads/pipelist
Today I was trying to write some, lets say, internet communicator.
I'm learning basics of Java (from instructables) and now it's time for network programming.
What I want my program to do:
If there is any data on input stream from network - get data, put it into string and print in a console.
If there is data in console - put it into string and send it by network.
When I try only send data from client app to server and print it in server console - everything works fine. But then I have different code (without getting and sending data two way).
I know that problem is in lines inside while(true) statements in line if(cin.hasNextLine()). I don't understand why it blocks whole app when it should be just returning false or true if there isn't or there is data in console (from keyboard).
The annoying is that it's working perfectly with reading files.
Oh. And also I tried to check IF data which I didn't typed into console is "". It didn't solved my problem.
Server code:
import java.net.*;
import java.io.*;
import java.util.*;
import java.time.LocalTime;
public class GreetingServer extends Thread {
private ServerSocket serverSocket;
public GreetingServer(int port) throws IOException {
serverSocket = new ServerSocket(port, 0);
serverSocket.setSoTimeout(30000);
}
public void run() {
while(true) {
try {
System.out.println("Waiting for client on port " + serverSocket.getLocalPort() + "...");
Socket server = serverSocket.accept();
System.out.println("Just connected to " + server.getRemoteSocketAddress());
DataInputStream in = new DataInputStream(server.getInputStream());
System.out.println(in.readUTF());
DataOutputStream out = new DataOutputStream(server.getOutputStream());
out.writeUTF("Thank you for connecting to " + server.getLocalSocketAddress());
FileWriter plik = new FileWriter("/home/greg/Dokumenty/logizserwera.txt", true);
System.out.println("StartTime: " + LocalTime.now());
Scanner cin = new Scanner(System.in);
String stringReadyToSend, stringGotFromClient = null;
while(true) {
System.out.println("Before hasnextline");
if(cin.hasNextLine()) {
stringReadyToSend = cin.nextLine();
out.writeUTF(stringReadyToSend);
}
if(in.available() != 0) {
stringGotFromClient = in.readUTF();
// EOT means End Of Transmission
if(stringGotFromClient.equals("EOT")) break;
else System.out.println("Message from client: " + stringGotFromClient();
}
else System.out.println("No message");
break;
}
System.out.println("EndTime: " + LocalTime.now());
server.close();
plik.close();
}
catch(SocketTimeoutException s) {
System.out.println("Socket timed out!");
break;
}
catch(IOException e) {
e.printStackTrace();
break;
}
}
}
public static void main(String[] args) {
int port = 6066;
try {
Thread t = new GreetingServer(port);
t.start();
}catch(IOException e) {
e.printStackTrace();
}
}
}
And client code:
import java.net.*;
import java.io.*;
import java.util.*;
public class GreetingClient {
public static void main(String[] args) {
String serverName = "localhost";
Scanner cin = new Scanner(System.in);
int port = 6066;
try {
System.out.println("Connecting to " + serverName + " on port " + port);
Socket client = new Socket(serverName, port);
System.out.println("Just connected to " + client.getRemoteSocketAddress());
OutputStream outToServer = client.getOutputStream();
DataOutputStream out = new DataOutputStream(outToServer);
out.writeUTF("Hello from " + client.getLocalSocketAddress());
InputStream inFromServer = client.getInputStream();
DataInputStream in = new DataInputStream(inFromServer);
System.out.println("Server says " + in.readUTF());
String lineReadyToSend, lineGotFromServer;
while(cin.hasNextLine()) {
if(cin.hasNextLine()) {
// EOT means End Of Transmission
lineReadyToSend = cin.nextLine();
if(lineReadyToSend.equals("EOT")) {
out.writeUTF(lineReadyToSend);
break;
}
else out.writeUTF(lineReadyToSend);
}
if(in.available() != 0) {
lineGotFromServer = in.readUTF();
System.out.println("Message from server: " + lineGotFromServer);
}
}
out.writeUTF("EOT");
client.close();
System.out.println("End of transmission. Server disconnected");
}catch(IOException e) {
e.printStackTrace();
}
}
}
You are using cin which is a Scanner for the System.in
Practically that just scans if there are entered lines on the console. Perhaps try doing that with the data input stream (in) on your server.
Well, everything looks god. Just a cuestion, do you execute both applications at same time? Well, if it's the case, could be the access to System.in resource. Remember this is a static field, and not instantiated. Try to run one of them in other location. A second hint: use try clause and watch the errors if there are, and use debuging or resource monitor tools to detect the problem.
I've connected to an already existent server that contains lines of strings I need to read in. Given that I only need to read in a String type, which input reader would work here so I could read line by line in my While loop? Here's my simple Client:
public class Client
{
public static final int PORT_NUMBER = 8888;
public static void main(String[] args)
{
int port = PORT_NUMBER;
String content;
OutputStream output;
InputStream input;
Socket s = null;
try
{
s = new Socket("server.example.exp", port);
output = s.getOutputStream();
input = s.getInputStream();
System.out.println("Connected to " + s.getInetAddress() + " on port " + s.getPort());
}
catch (IOException e) {System.err.println(e);}
while (true)
{
try
{
//read next line from server
}
catch (EOFException eof){
System.out.println("eof encountered" + eof.getMessage());
break;
}
catch (OptionalDataException ode){System.out.println("OptionalDataException" + ode.getMessage());}
catch (IOException ioe){System.out.println("IOException on read object");}
catch (ClassNotFoundException cnf){System.out.println("ClassNotFoundException");}
}
}
}
I know it's a very basic question, I'm just having trouble getting started, is all. I appreciate any clarification. Thanks.
To read from an InputStream, you can wrap it in a InputStreamReader, and then a BufferedReader, from which you can readLine:
BufferedReader input;
input = new BufferedReader(new InputStreamReader(s.getInputStream()));
Then:
while(true){
try{
input.readLine();//Read from server
}
Add the folloWing line before your while
BufferedReader inp2 = new BufferedReader(new InputStreamReader(inp));
while (true) {
try {
inp2.readLine();
}
}
I want to run OSGi framework on another computer (in a main method). So I wanted to know is there any way to connect to the OSGi console from the other computer and manage bundles?
I thought maybe using a java.net.Socket would help, and that's how I implemented that. I've used 2 threads. one for processing user input stream, and the other one that processes OSGi Console response. This is the first thread (processes user input stream):
configMap.put("osgi.console", "6666");
Framework fwk = ff.newFramework(configMap);
try {
fwk.start();
} catch (BundleException e) {
e.printStackTrace();
}
//__________________________________________________________________//
try {
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
Socket socket = new Socket(InetAddress.getByName("0.0.0.0"), 6666);
printlnInfo("Socket has been created: " + socket.getInetAddress() + ":" + socket.getPort());
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
ConsoleOutputReciever fr = new ConsoleOutputReciever();
new Thread(fr).start();
while (true) {
String userInput = "";
while ((userInput = stdIn.readLine()) != null) {
System.out.println("--> " + userInput);
out.write(userInput + "\n");
out.flush();
}
System.out.println("2");
}
} catch (Exception e1) {
e1.printStackTrace();
}
This is the second thread (processes OSGi Console response):
public class ConsoleOutputReciever implements Runnable {
public Scanner in = null;
#Override
public void run() {
printlnInfo("ConsoleOutputReciever Started");
try {
Socket socket = new Socket(InetAddress.getByName("0.0.0.0"), 6666);
printlnInfo("Socket has been created: " + socket.getInetAddress() + ":" + socket.getPort());
String osgiResponse = "";
in = new Scanner(socket.getInputStream());
try {
while (true) {
in = new Scanner(socket.getInputStream());
while (in.hasNext()) {
System.out.println("-- READ LOOP");
osgiResponse = in.nextLine();
System.out.println("-- " + osgiResponse);
}
}
} catch (IllegalBlockingModeException e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
but I only receive the first response of the OSGi console. like this:
--READ LOOP
--
--READ LOOP
ss
--> ss
Any ideas about the problem or any other way to connect to OSGi console remotely?
you are using blocking io, thus your inner while loop will never finish until the socket is closed. you need 2 threads to accomplish this with blocking io streams. 1 thread reads from stdin and writes to the socket output stream, the other thread reads from the socket input stream and writes to stdout.
also, you probably want to write a newline after sending the userInput to the osgi console (Scanner.nextLine() eats the newline).
lastly, you don't generally want to use the Print* classes when working with sockets as they hide IOExceptions.
Instead of building your own thing you might want to use one of the remote shells that are available, for example the Apache Felix one at http://felix.apache.org/site/apache-felix-remote-shell.html
This is my code:
private String receiveData(String sjson) {
Log.i(TAG,"send request: " + sjson);
String jstr="";
try {
OutputStream out = s.getOutputStream();
out.write(sjson.getBytes());
out.flush();
//out.close();
Log.v(TAG,"sended data");
BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream()));
char[] cbuf = new char[1];
input.read(cbuf);
String size = new String(cbuf);
while (input.read(cbuf) != 0) {
if((new String(cbuf)).equals("{") == true)
break;
size = size + new String(cbuf);
}
char[] jbuf = new char[Integer.valueOf(size)];
input.read(jbuf);
jstr = "{" + new String(jbuf);
}catch (Exception e) {
Log.e(TAG,e.toString());
}
Log.d(TAG,"responce: " + jstr);
return jstr;
}
public void connectSocket() {
Log.v(TAG,"connecting Socket: "+URL+":"+PORT);
try {
s = new Socket(URL, PORT);
Log.v(TAG,"connect Socket!");
ERROR_CODE = 0;
}catch (Exception e) {
Log.e(TAG,e.toString());
ERROR_CODE = ERROR_SOCKET_CONNECT_SUCCESSFULL;
}
Log.e(TAG,getErrorMsg(ERROR_CODE));
}
public void closeSocket() {
Log.v(TAG,"closeSocket");
try {
s.close();
}catch (Exception e) {
Log.e(TAG,e.toString());
}
}
At server the answer is less than a second. At the client it passes 1 minute before reading data.
Apps stoped at input.read(cbuf); waiting for answer.
Logs:
05-23 06:35:17.540: VERBOSE/Utilits(358): Auth: 77.221.129.100:10598
05-23 06:35:17.660: INFO/Utilits(358): send request: 0119{"data":{"password":"12345","imei":"000000000000001"},"method":"login"}
05-23 06:36:17.909: DEBUG/Utilits(358): responce: {"response":{"success":true,"user":{"id":"6","properties":{"auto":"model":"audi","color":"ffff","number":"td123r"}},"is_driver":"1"}}}
Why does it take so long to read an answer?
What on earth do you expect that method to do? There are bugs in it, and it does things that it should do.
You should specify encoding/charset when you create the InputStreamReader
Why do you read character by character from start to "{"
Why do you create a string for each character that you read before you hit "{"
Why do you append strings in a loop? Use a StringBuilder if you must append.
input.read returns an integer that says how many bytes/character that you have received
It's never guaranteed that it will fill the buffer. So you might not get all data.
Why aren't you closing resources?
.. and now to why it might be slow. Is the server flushing the data? If not, make sure that the server is flushing the data.