I have a problem when I try to connect my physical device to my server using sockets. On the server side it does not seem to accept any connection while on the client side the socket times out. Any ideas why this is happening?
I provide my code below
Server Code:
public void run()
{
// TODO Auto-generated method stub
try{
gamePending = false;
pid = 0;
while(pid < 2){
System.out.println("Hello from run loop on game");
Socket tempSocket = server.accept();
System.out.println("Client connected at " + tempSocket.getLocalPort());
PrintWriter tempWriter = new PrintWriter(new BufferedWriter (new OutputStreamWriter(tempSocket.getOutputStream())),true);
tempWriter.println("" + pid);
players[pid] = new Client(tempSocket, pid, this);
players[pid].start();
gamePending = true;
if(pid == 0){sendMsg(pid, "waiting for other player");}
pid++;
}
}
catch(Exception e){
System.out.println("There has been an Error. Game will be Terminated.");
}
//Start new game for the next two players...
new Game();
}
Client Side:
public void run() {
// Connects to the Server....
try {
socket = new Socket("192.168.1.116", 9090);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
in = new BufferedReader (new InputStreamReader(socket.getInputStream()));
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
out = new PrintWriter(socket.getOutputStream(),true);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
11-16 23:32:11.016: W/System.err(24213): java.net.ConnectException: failed to connect to /192.168.1.116 (port 9090): connect failed: ETIMEDOUT (Connection timed out)
11-16 23:32:11.016: W/System.err(24213): at libcore.io.IoBridge.connect(IoBridge.java:114)
11-16 23:32:11.016: W/System.err(24213): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
11-16 23:32:11.026: W/System.err(24213): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:459)
11-16 23:32:11.026: W/System.err(24213): at java.net.Socket.connect(Socket.java:842)
11-16 23:32:11.026: W/System.err(24213): at vatos.locos.spheroknockout.Connection.run(Connection.java:22)
11-16 23:32:11.026: W/System.err(24213): at java.lang.Thread.run(Thread.java:841)
11-16 23:32:11.026: W/System.err(24213): Caused by: libcore.io.ErrnoException: connect failed: ETIMEDOUT (Connection timed out)
}
I can't be sure (because it does not appear in your code) but I think the server is not hosing on the same port (9090). That may be the main problem, but the server or client may also be blocked by a firewall (even if they run on the same machine).
Related
I want to send a simple string to a server on my desktop PC. Here is what I have on my PC:
public static void main(String[] args) {
System.out.println("Server Started");
Server server = new Server();
server.start();
}
public void start(){
try {
ServerSocket SRVSOCK = new ServerSocket(333);
Socket SOCK = SRVSOCK.accept();
InputStreamReader ir = new InputStreamReader(SOCK.getInputStream());
BufferedReader bf = new BufferedReader(ir);
String MESSAGE = bf.readLine();
System.out.println(MESSAGE);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
For my android tablet I have this in the onCreate():
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Thread tthread = new Thread(new Runnable(){
#Override
public void run() {
Connect();
}});
}
public void Connect(){
try {
Socket SOCK = new Socket("10.0.0.3", 333);
PrintWriter pw = new PrintWriter(SOCK.getOutputStream());
pw.println("FROM ANDROID!");
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I have seen you can create a new thread which you need (otherwise the app UI freezes), but it still does not send the text to my server, I have added the incoming and outgoing port in my windows firewall, and even tried to turn off the firewall, but still no luck..
The android code is running on a real physical tablet (Nexus 7 2013) and not an emulator.
What is wrong here?
This whats in my log cat when the app is opened
03-24 13:43:59.695: I/ActivityManager(768): START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.hashimo.mcpeworldconverter/.MainActivity bnds=[200,1314] [400,1590] (has extras)} from uid 10022 on display 0
03-24 13:43:59.780: I/ActivityManager(768): Start proc com.hashimo.mcpeworldconverter for activity com.hashimo.mcpeworldconverter/.MainActivity: pid=6724 uid=10140 gids={50140, 9997, 1028, 1015, 3003} abi=armeabi-v7a
03-24 13:44:00.338: I/ActivityManager(768): Displayed com.hashimo.mcpeworldconverter/.MainActivity: +592ms
You are declaring a Thread but you forgot to .start() it. So your code is not executed.
Hi there I have 2 classes in order to push a file into an android device.
My Server CLass:
public class FileServer {
public static void main (String [] args ) throws IOException {
// create socket
ServerSocket servsock = new ServerSocket(13267);
while (true) {
System.out.println("Waiting...");
Socket sock = servsock.accept();
System.out.println("Accepted connection : " + sock);
// sendfile
File myFile = new File ("C:\\Users\\Petrica\\Desktop\\zzz.txt");
byte [] mybytearray = new byte [(int)myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
bis.read(mybytearray,0,mybytearray.length);
OutputStream os = sock.getOutputStream();
System.out.println("Sending...");
os.write(mybytearray,0,mybytearray.length);
os.flush();
sock.close();
}
}
}
And my Client Class:
public class TCPClient extends AsyncTask{
#Override
protected Object doInBackground(Object... params) {
int filesize=6022386; // filesize temporary hardcoded
long start = System.currentTimeMillis();
int bytesRead;
int current = 0;
// localhost for testing
Socket sock = null;
try {
sock = new Socket("127.0.0.1",13267);
} catch (UnknownHostException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println("Connecting...");
// receive file
try {
byte [] mybytearray = new byte [filesize];
InputStream is = sock.getInputStream();
FileOutputStream fos = new FileOutputStream("/mnt/sdcard/zzz.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
bytesRead = is.read(mybytearray,0,mybytearray.length);
current = bytesRead;
// thanks to A. Cádiz for the bug fix
do {
bytesRead =
is.read(mybytearray, current, (mybytearray.length-current));
if(bytesRead >= 0) current += bytesRead;
} while(bytesRead > -1);
bos.write(mybytearray, 0 , current);
bos.flush();
long end = System.currentTimeMillis();
System.out.println(end-start);
bos.close();
sock.close();
// TODO Auto-generated method stub
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
I get an error
09-09 15:52:39.261: E/AndroidRuntime(802): FATAL EXCEPTION: AsyncTask #1
09-09 15:52:39.261: E/AndroidRuntime(802): java.lang.RuntimeException: An error occured while executing doInBackground()
09-09 15:52:39.261: E/AndroidRuntime(802): at android.os.AsyncTask$3.done(AsyncTask.java:299)
09-09 15:52:39.261: E/AndroidRuntime(802): at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
09-09 15:52:39.261: E/AndroidRuntime(802): at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
09-09 15:52:39.261: E/AndroidRuntime(802): at java.util.concurrent.FutureTask.run(FutureTask.java:239)
09-09 15:52:39.261: E/AndroidRuntime(802): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
09-09 15:52:39.261: E/AndroidRuntime(802): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
09-09 15:52:39.261: E/AndroidRuntime(802): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
09-09 15:52:39.261: E/AndroidRuntime(802): at java.lang.Thread.run(Thread.java:841)
09-09 15:52:39.261: E/AndroidRuntime(802): Caused by: java.lang.NullPointerException
09-09 15:52:39.261: E/AndroidRuntime(802): at com.aaaaaa.TCPClient.doInBackground(TCPClient.java:33)
09-09 15:52:39.261: E/AndroidRuntime(802): at com.aaaaaa.TCPClient.doInBackground(TCPClient.java:1)
09-09 15:52:39.261: E/AndroidRuntime(802): at android.os.AsyncTask$2.call(AsyncTask.java:287)
09-09 15:52:39.261: E/AndroidRuntime(802): at java.util.concurrent.FutureTask.run(FutureTask.java:234)
09-09 15:52:39.261: E/AndroidRuntime(802): ... 4 more
MainActivity:
public class MainActivity extends Activity {
TCPClient tcpc;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn = (Button) findViewById(R.id.send_button);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
tcpc.execute();
}
});
}
}
Does anyone have an idea what should I do ??? In the future i would like to send 2 files :D .Thanks in advice .
You're really expected to be able to sort out your own NullPointerExceptions: at least I expect it, but when you get past that, your copy code is wrong. You are presently ignoring the count returned by read() and assuming it fills the buffer. It isn't guaranteed to do that. See the Javadoc.
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
Use this at both ends, with any buffer size > 0, typically 8192.
I don't think your Socket is connecting, but its hard to tell. IN your log output, it says NullPointerException caused by doInBackground() line 33. You should check line 33 in your editor, and better yet, show us in your post which line is 33. I kind of have a feeling that you call Socket sock = null;, then you try and instantiate a new Socket in a try block, but that fails, so sock still == null, then you call a method on sock, and boom, NPE.
If you are running the Server on a computer, and the AsyncTask on an Android device, you won't be able to try and connect to localhost (127.0.0.1). You should instead try to connect to the internal network ip of your computer (something like 192.168.1.XXX), assuming both devices are on WiFi. If you are running an android emulator, then 127.0.0.1 refers back to the emulated device, and all emulator sessions run on an emulated router that you will have to configure for port forwarding before you can refer to the development machine, see here-->http://developer.android.com/tools/devices/emulator.html#emulatornetworking
As Andras Balazs Lajtha says, it looks like TCPClient isn't ever initialized/created during onCreate(), it is only declared. Since your logcat output shows errors from TCPClient though, I assume you have that code actually running.
In general, when you post a log output that refers to problems with a specific line of code, you should start there, and when you post, tell us or show us which line that is. And of course, if line 33 isn't related to a null Socket object, then I haven't been much help at all :)
I'm trying to implement some simple caching into my application and I'm having some issues.
Basically my code scrapes a webpage, gets some regex matches and puts them into an ArrayList. This takes a while to do (a few seconds, but this happens frequently) so I'm trying to implement a simple caching system which checks when the cache file was modified, if this is older than a week, refresh cache.
My problem lies with storing the ArrayList, can anyone help with this?
I originally have (which works)
private List<String> getVideoIDS(final String url2) {
if (android.os.Environment.getDataDirectory().equals(android.os.Environment.MEDIA_MOUNTED)) //android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
cacheDir=new File(android.os.Environment.getDataDirectory(),"PL" + url.getQuery());
else
cacheDir=mContext.getCacheDir();
if(!cacheDir.exists())
cacheDir.mkdirs();
File f = new File(cacheDir, "PL"+url.getQuery());
if (f.lastModified() > 604800000 || f.exists() == false) {
String expr = "(?<=v=)[a-zA-Z0-9-_]{11}(?=&)|(?<=[0-9]/)[^&\n]{11}|(?<=v=)[^&\n]{11}";
int count = 0;
Pattern patt = Pattern.compile(expr,
Pattern.DOTALL | Pattern.UNIX_LINES | Pattern.CASE_INSENSITIVE);
try {
url = new URL(url2);
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
m = patt.matcher(getURLContent(url));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while (m.find()) {
if ("default.jpg".equals(m.group(0)) || "videos?view".equals(m.group(0))) {
//Do nothing
} else {
allMatches.add(m.group(0));
count++;
Log.i("", m.group(0));
}
}
//Remove duplicates
List<String> noDupes = new ArrayList<String>();
Iterator iterator = allMatches.iterator();
while (iterator.hasNext())
{
String o = (String) iterator.next();
if(!noDupes.contains(o)) noDupes.add(o);
}
allMatches = noDupes;
return allMatches; }
Now what I'm trying to modify this to be is this (in theory, as it currently doesn't work)
private List<String> getVideoIDS(final String url2) {
if (android.os.Environment.getDataDirectory().equals(android.os.Environment.MEDIA_MOUNTED)) //android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
cacheDir=new File(android.os.Environment.getDataDirectory(),"PL" + url.getQuery());
else
cacheDir=mContext.getCacheDir();
if(!cacheDir.exists())
cacheDir.mkdirs();
File f = new File(cacheDir, "PL"+url.getQuery());
if (f.lastModified() > 604800000 || f.exists() == false) {
String expr = "(?<=v=)[a-zA-Z0-9-_]{11}(?=&)|(?<=[0-9]/)[^&\n]{11}|(?<=v=)[^&\n]{11}";
int count = 0;
Pattern patt = Pattern.compile(expr,
Pattern.DOTALL | Pattern.UNIX_LINES | Pattern.CASE_INSENSITIVE);
try {
url = new URL(url2);
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
m = patt.matcher(getURLContent(url));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while (m.find()) {
if ("default.jpg".equals(m.group(0)) || "videos?view".equals(m.group(0))) {
//Do nothing
} else {
allMatches.add(m.group(0));
count++;
Log.i("", m.group(0));
}
}
//Remove duplicates
List<String> noDupes = new ArrayList<String>();
Iterator iterator = allMatches.iterator();
while (iterator.hasNext())
{
String o = (String) iterator.next();
if(!noDupes.contains(o)) noDupes.add(o);
}
allMatches = noDupes;
ObjectOutputStream save = null;
FileOutputStream saveFile = null;
try {
saveFile = new FileOutputStream(cacheDir + "PL"+url.getQuery());
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// Create an ObjectOutputStream to put objects into save file.
try {
save = new ObjectOutputStream(saveFile);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
save.writeObject(allMatches);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
save.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return allMatches;}
else {
try{
// Open file to read from, named SavedObjects.sav.
FileInputStream saveFile = new FileInputStream(cacheDir + "PL"+url.getQuery());
// Create an ObjectInputStream to get objects from save file.
final ObjectInputStream save = new ObjectInputStream(saveFile);
// Now we do the restore.
// readObject() returns a generic Object, we cast those back
// into their original class type.
// For primitive types, use the corresponding reference class.
allMatches = (ArrayList) save.readObject();
// Close the file.
save.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (StreamCorruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
// This also closes saveFile.
}
} return allMatches;
}
Note: I'm trying to save multiple files as this method is called for various different categories. That should be handled with calling the file a different filename based on whats open. I think I have implemented this correctly.
Stacktrace is as follows
04-03 17:41:20.846: E/AndroidRuntime(2438): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.test.test/com.test.test.VideoGrid}: java.lang.NullPointerException
04-03 17:41:20.846: E/AndroidRuntime(2438): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2194)
04-03 17:41:20.846: E/AndroidRuntime(2438): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2229)
04-03 17:41:20.846: E/AndroidRuntime(2438): at android.app.ActivityThread.access$600(ActivityThread.java:139)
04-03 17:41:20.846: E/AndroidRuntime(2438): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1261)
04-03 17:41:20.846: E/AndroidRuntime(2438): at android.os.Handler.dispatchMessage(Handler.java:99)
04-03 17:41:20.846: E/AndroidRuntime(2438): at android.os.Looper.loop(Looper.java:154)
04-03 17:41:20.846: E/AndroidRuntime(2438): at android.app.ActivityThread.main(ActivityThread.java:4944)
04-03 17:41:20.846: E/AndroidRuntime(2438): at java.lang.reflect.Method.invokeNative(Native Method)
04-03 17:41:20.846: E/AndroidRuntime(2438): at java.lang.reflect.Method.invoke(Method.java:511)
04-03 17:41:20.846: E/AndroidRuntime(2438): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
04-03 17:41:20.846: E/AndroidRuntime(2438): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
04-03 17:41:20.846: E/AndroidRuntime(2438): at dalvik.system.NativeStart.main(Native Method)
04-03 17:41:20.846: E/AndroidRuntime(2438): Caused by: java.lang.NullPointerException
04-03 17:41:20.846: E/AndroidRuntime(2438): at java.io.DataOutputStream.writeShort(DataOutputStream.java:192)
04-03 17:41:20.846: E/AndroidRuntime(2438): at java.io.ObjectOutputStream.writeStreamHeader(ObjectOutputStream.java:1815)
04-03 17:41:20.846: E/AndroidRuntime(2438): at java.io.ObjectOutputStream.<init>(ObjectOutputStream.java:279)
04-03 17:41:20.846: E/AndroidRuntime(2438): at com.test.test.VideoGrid.getVideoIDS(VideoGrid.java:204)
04-03 17:41:20.846: E/AndroidRuntime(2438): at com.test.test.VideoGrid.onCreate(VideoGrid.java:74)
04-03 17:41:20.846: E/AndroidRuntime(2438): at android.app.Activity.performCreate(Activity.java:4524)
04-03 17:41:20.846: E/AndroidRuntime(2438): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1071)
04-03 17:41:20.846: E/AndroidRuntime(2438): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2150)
This
com.test.test.VideoGrid.getVideoIDS(VideoGrid.java:204)
Points to
save = new ObjectOutputStream(saveFile);
I have
android.permission.WRITE_EXTERNAL_STORAGE
In my manifest
I have tried changing the filename to something static (1) instead of my url.getQuery incase that was the problem - doesn't change anything, exact same problem.
I feel I'm making a fundamental error here. Can anyone see where I'm going wrong with saving/reading the ArrayList?
It looks like your save file wasn't found; but its hard to tell since your code is currently swallowing all of the exceptions. instead of :
try {
saveFile = new FileOutputStream(cacheDir + "PL"+url.getQuery())
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Try logging your exceptions instead, since e.printStackTrace(); doesn't do anything by default on android.
catch(FileNotFoundException e1) {
Log.e(getClass().getName(), "File not found:" + cacheDir + "PL" + url.getQuery()", e1);
}
Anyway, that's my theory - your file path is pointing to somewhere that can't be written to for whatever reason (the docs have some possible explanations); saveFile then comes out of the exception as null, and then you pass the null parameter into the outputStream constructor
I am writing an application that communicates using sockets. I have a server running on one android emulator on a computer, then i have 2 other clients running on android emulators on 2 other computers. I am trying to get the 2 clients to connect to the server.
This works when i run the server and clients on the same computer, but when i attempt to do this on the same wifi network and on separate computers it gives me the following error. The client and server code is posted below. A lot is stripped out just to show the important stuff. Also, after the server starts i telnet into the server and run these commands redir add tcp:5000:6000 (i have also tried without doing the redir but it still says the same thing). Then i start the clients and get the error. Thanks for the help!
Both the 5000 port and 6000 port are open on my router. And i have windows firewall disabled on the computer hosting the server.
11-27 18:54:02.274: W/ActivityManager(60): Activity idle timeout for HistoryRecord{44cf0a30 school.cpe434.ClassAidClient/school.cpe434.ClassAid.ClassAidClient4Activity}
11-27 18:57:02.424: W/System.err(205): java.net.SocketException: The operation timed out
11-27 18:57:02.454: W/System.err(205): at org.apache.harmony.luni.platform.OSNetworkSystem.connectSocketImpl(Native Method)
11-27 18:57:02.454: W/System.err(205): at org.apache.harmony.luni.platform.OSNetworkSystem.connect(OSNetworkSystem.java:114)
11-27 18:57:02.465: W/System.err(205): at org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:245)
11-27 18:57:02.465: W/System.err(205): at org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:220)
11-27 18:57:02.465: W/System.err(205): at java.net.Socket.startupSocket(Socket.java:780)
11-27 18:57:02.465: W/System.err(205): at java.net.Socket.<init>(Socket.java:314)
11-27 18:57:02.465: W/System.err(205): at school.cpe434.ClassAid.ClassAidClient4Activity.onCreate(ClassAidClient4Activity.java:102)
11-27 18:57:02.474: W/System.err(205): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
11-27 18:57:02.474: W/System.err(205): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459)
11-27 18:57:02.474: W/System.err(205): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
11-27 18:57:02.474: W/System.err(205): at android.app.ActivityThread.access$2200(ActivityThread.java:119)
11-27 18:57:02.474: W/System.err(205): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)
11-27 18:57:02.474: W/System.err(205): at android.os.Handler.dispatchMessage(Handler.java:99)
11-27 18:57:02.474: W/System.err(205): at android.os.Looper.loop(Looper.java:123)
11-27 18:57:02.486: W/System.err(205): at android.app.ActivityThread.main(ActivityThread.java:4363)
11-27 18:57:02.486: W/System.err(205): at java.lang.reflect.Method.invokeNative(Native Method)
11-27 18:57:02.486: W/System.err(205): at java.lang.reflect.Method.invoke(Method.java:521)
11-27 18:57:02.486: W/System.err(205): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
11-27 18:57:02.486: W/System.err(205): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
11-27 18:57:02.486: W/System.err(205): at dalvik.system.NativeStart.main(Native Method)
The server code
public class ClassAidServer4Activity extends Activity {
ServerSocket ss = null;
String mClientMsg = "";
String mClientExtraMsg = "";
Thread myCommsThread = null;
public static final int SERVERPORT = 6000;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView tv = (TextView) findViewById(R.id.textView1);
tv.setText("Nothing from client yet");
this.myCommsThread = new Thread(new CommsThread());
this.myCommsThread.start();
}
class CommsThread implements Runnable {
public void run() {
// Socket s = null;
try {
ss = new ServerSocket(SERVERPORT );
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
while(true) {
try {
Socket socket = ss.accept();
connectedDeviceCount++;
Thread lThread = new Thread(new ListeningThread(socket));
lThread.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class ListeningThread implements Runnable {
private Socket s = null;
public ListeningThread(Socket socket) {
// TODO Auto-generated constructor stub
this.s = socket;
}
#Override
public void run() {
// TODO Auto-generated method stub
while (!Thread.currentThread().isInterrupted()) {
Message m = new Message();
// m.what = QUESTION_ID;
try {
if (s == null)
s = ss.accept();
BufferedReader input = new BufferedReader(
new InputStreamReader(s.getInputStream()));
String st = null;
st = input.readLine();
String[] temp = parseReadMessage(st);
mClientMsg = temp[1];
if(temp.length > 2) {
mClientExtraMsg = temp[2];
}
m.what = Integer.parseInt(temp[0]);
myUpdateHandler.sendMessage(m);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
The client code
public class ClassAidClient4Activity extends Activity {
//telnet localhost 5554
//redir add tcp:5000:6000
private Socket socket;
private String serverIpAddress = "192.168.1.102";
// if "redir add" is disabled this should be 6000
private static final int REDIRECTED_SERVERPORT = 5000;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try {
InetAddress serverAddr = InetAddress.getByName(serverIpAddress);
socket = new Socket(serverAddr, REDIRECTED_SERVERPORT);
} catch (UnknownHostException e1) {
mQuestionAdapter.add("UnknownHostException");
e1.printStackTrace();
} catch (IOException e1) {
mQuestionAdapter.add("IOException");
e1.printStackTrace();
}
}
}
I figured it out. I needed to create a proxy. I used this SO post as a reference. And heavily modified this code to work for multiple connections. It is working now. HOORAY!
again i have got a problem with socket programming in Android. My Problem is Selector.select() returns zero that there are no SocketChannels ready for writing. And again the same code works in normal Java but does not work in Android. Here is my code:
package com.test;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
public class WebSocketTest extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
SocketChannel channel = null;
SocketAddress socketAdress = new InetSocketAddress("10.0.0.1", 8787);
try {
channel = SocketChannel.open();
} catch (IOException e) {
Log.e("ERROR", "channel open");
}
try {
channel.configureBlocking(false);
} catch (IOException e1) {
Log.e("ERROR", "channel blocking");
}
try {
channel.connect(socketAdress);
} catch (IOException e) {
Log.e("ERROR", "channel connect");
}
try {
while(!channel.finishConnect())
{
}
} catch (IOException e1) {
Log.e("ERROR", "channel finishConnect");
}
Selector selector = null;
try {
selector = Selector.open();
} catch (IOException e) {
Log.e("ERROR", "selector open");
}
try {
channel.register(selector, channel.validOps());
} catch (ClosedChannelException e) {
Log.e("ERROR", "channel register");
}
boolean i = true;
while(i)
{
int readyChannels = 0;
try {
readyChannels = selector.select();
} catch (IOException e) {
Log.e("ERROR", "selector select");
}
if(readyChannels > 0)
{
i = false;
}
}
}
}
In Java readyChannels = 1. In Android it is 0.
Can anyone help me?
Emulator sits behind a virtual router. You need to configure Network Redirections (port forwarding) to make a certain port on emulator visible to the outside network (including your computer).
There are several issues with this NIO code.
Instead of connecting and then spinning around finishConnect(), possibly forever, you should connect before going into non-blocking mode. At the moment you're just burning the CPU, flattening the battery, etc.
You should only register OP_WRITE when you have something to write. It is normally 'ready', so if you register the channel for it permanently your selection loop will just spin. The only time OP_WRITE isn't ready is when you have filled the socket send buffer.