In my Android project I implemented a Faye client. But, when I call SocketChannel.socket().connect(...), the connection hangs and the next line does not run. It is as if I don`t set the timeout, or disconnect for timeout.
Thread.currentThread().setName("WebSocketConnector");
try {
// "java.net.SocketException: Address family not supported by protocol"
System.setProperty("java.net.preferIPv6Addresses", "false");
mTransportChannel = SocketChannel.open();
// mTransportChannel.configureBlocking(false);
// the following will block until connection was established or
// an error occurred!
mTransportChannel.socket().connect(
new InetSocketAddress(mWsHost, mWsPort), mOptions.getSocketConnectTimeout());
Log.i(TAG, "Socket connected");
// before doing any data transfer on the socket, set socket
// options
mTransportChannel.socket().setSoTimeout(
mOptions.getSocketReceiveTimeout());
mTransportChannel.socket().setTcpNoDelay(
mOptions.getTcpNoDelay());
return null;
} catch (IOException e) {
Log.e(TAG, e.getMessage());
return e.getMessage();
}
If I did so:
mTransportChannel = SocketChannel.open();
mTransportChannel.configureBlocking(false);
mTransportChannel.connect(socketAddress);
SocketChannel .isConnected() return false
What is the problem I don't understand?
DNS resolution might be blocking even before the connect() call. Put new InetSocketAddress(mWsHost, mWsPort) on a separate line, and print out its results. Chances are you are stuck there.
If that's not the case, check if you can connect to the target host/port with telnet:
~$ telnet host port
This problem is resolved. My wifi connection didn`t have access to private resource. But how I have other problem with web socket. It is
Android socket read method return -1
Related
I am trying to connect to a ELM327 device via bluetooth.
The library I am using:
https://github.com/eltonvs/java-obd-api
Establishing a bluetooth connection works fine and I can reset the device:
BluetoothDevice device = bluetoothAdapter.getRemoteDevice(deviceAddress);
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
final BluetoothSocket socket;
try {
socket = device.createInsecureRfcommSocketToServiceRecord(uuid);
socket.connect();
Log.d("xx", "1. Reset");
ObdResetCommand obdResetCommand = new ObdResetCommand();
obdResetCommand.run(socket.getInputStream(), socket.getOutputStream());
System.out.println(obdResetCommand.getFormattedResult());
Log.d("xx", "2. Echo Off");
EchoOffCommand echoOffCommand = new EchoOffCommand();
echoOffCommand.run(socket.getInputStream(), socket.getOutputStream());
System.out.println(echoOffCommand.getFormattedResult());
Log.d("xx", "3. LineFeed Off");
LineFeedOffCommand lineFeedOffCommand = new LineFeedOffCommand();
lineFeedOffCommand.run(socket.getInputStream(), socket.getOutputStream());
System.out.println(lineFeedOffCommand.getFormattedResult());
}
Output:
D/xx: 1. Reset
I/System.out: ELM327v1.5
D/xx: 2. Echo Off
I/System.out: OK
D/xx: 3. LineFeed Off
I/System.out: OK
The part that is not working is to select the protocol and read a voltage value:
SelectProtocolCommand selectProtocolCommand = new SelectProtocolCommand(ObdProtocols.AUTO);
try {
selectProtocolCommand.run(socket.getInputStream(), socket.getOutputStream());
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
ModuleVoltageCommand moduleVoltageCommand = new ModuleVoltageCommand();
try {
moduleVoltageCommand.run(socket.getInputStream(), socket.getOutputStream());
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
What I observe is that the protocol selection is finished very quickly without any output. When I compare the protocol selection part to other apps like "torque lite", this takes much longer and I see flashing lights on my ELM327 device, which is not the case when running my code.
The ModuleVoltageCommand crashes then with:
br.ufrn.imd.obd.exceptions.UnableToConnectException: Error running
Control Module Power Supply [01 42], response: ...UNABLETOCONNECT
I verified the dongle is working with other apps, so this must be an issue with my code.
What am I doing wrong?
I'm the creator of this library, thanks for using my project!
This is an issue with the ECU, when you change the protocol, the next command will usually fail. What I usually do is sending a dump command that's expected to fail (so you just ignore any raised exception for this command) and then I send the commands I really want to run.
Hope it solves your issue!
My situation:
I'm trying to create an android app using unity that has a server running, so I can call the service from a PC.
However, when I try to connect to the server I get the error message:
SocketException: No connection could be made because the target machine actively refused it.
System.Net.Sockets.Socket.Connect (System.Net.EndPoint remoteEP, Boolean requireSocketPolicy)
System.Net.Sockets.Socket.Connect (System.Net.EndPoint remoteEP)
System.Net.Sockets.TcpClient.Connect (System.Net.IPEndPoint remote_end_point)
System.Net.Sockets.TcpClient.Connect (System.Net.IPAddress[] ipAddresses, Int32 port)
Doing ping on the IP Address is fine, so the host is reachable, as far as I know android devices don't have firewalls, so my guess it is a problem with the port.
Currently I'm trying to run the service on port 9096, which works if I just run the application in the editor. Is this a valid port for android?
If not, what would be a valid one?
Do you have any other ideas on what the problem could be?
Thank you.
Additional info:
The device is Google Tango and I want to use Thrift to create a server and access the location of the device from a windows coomputer.
========================================================
UPDATE: included code for server and client
public void startServerService()
{
try
{
TangoService.Processor processor = new TangoService.Processor(this);
serverTransport = new TServerSocket(9096);
server = new TThreadPoolServer(processor, serverTransport);
Debug.Log("Starting the server...");
server.Serve();
}
catch (UnityException e)
{
Debug.Log(e);
}
}
void startClient()
{
try{
TTransport transport = new TSocket(ipAddress, 9096);
transport.Open ();
TProtocol protocol = new TBinaryProtocol(transport);
client=new TangoService.Client(protocol);
}
catch(UnityException e)
{
Debug.Log(e);
}
}
Im making a lua script running at my pc, and need to connect from my android.
So in the lua script I just put this:
local socket = require 'socket'
local server = socket.tcp()
print("createdserver")
server:bind('*',7070)
print("binded")
while 1 do
server:listen(32)
local client = server:accept()
-- make sure we don't block waiting for this client's line
client:settimeout(10)
-- receive the line
local line, err = client:receive()
-- if there was no error, send it back to the client
if not err then client:send(line .. "\n") end
-- done with client, close the object
client:close()
end
And at android I got a really simple socket connection:
public Connection(String ip, int _port) {
//inMessage = new NetworkMessage();
buffer = new byte[16394];
try {
serverAddres = InetAddress.getByName(ip);
socket = new Socket(serverAddres, _port);
socketOut = socket.getOutputStream();
} catch (IOException e) {
Log.e("Connect", e.getMessage());
}
}
At android it just stays at "new Socket" and dont connect.
Im not familiar with lua but my understanding is that you are writing a new line to the socket and you want to receive on the Android side.
Normally if that is the case you need to get the inputStream not the output one since you are waiting for results. Furthermore you need to indefinitely (or till some conditions are met) to listen to the input stream for data on a separate thread (a standard in):
while(true){
if (inputStreamReader().read() != -1){
// do you processing
}
}
My notebook was changing its IP address so I couldnt reach it from the android, already solved!
So I have TCP server in Windows that is programmed in C++ and a client in JAVA, Android 4.0.4.
In Android, I connect like this:
public boolean sendConnectRequest()
{
while (isSocketConnected == false)
{
try {
if(comSocket == null)
comSocket = new Socket("192.168.0.1",1531);
isSocketConnected = comSocket.isConnected();
if (isSocketConnected) {
out = comSocket.getOutputStream();
in = comSocket.getInputStream();
}
else
comSocket.close();
}
catch (IOException ex)
{
Log.e("TCP Error", ex.getLocalizedMessage());
}
}
return true;
}
I typically have no problems with this code on the first connection to the server.
When i disconnect from the server, I call this:
public void closeConnection() {
if (comSocket != null)
{
try {
comSocket.close();
isSocketConnected = false;
if (out != null)
out.close();
if (in != null)
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
So here is the problem... I hit the home button on the smartphone, which places the program in pause. I start the program again and it calls the resume function in activity, which in turn starts the process toward reconnection. The connection is attempted and i get no errors. However, my Windows server records no connection. In Windows, I know that I am still blocked at:
SOCKET connectionSocket = accept(tcpNetworkData->socket, (struct sockaddr*)&from, &fromlen);
I believe this is normal. When I am in debug mode on the Android side, I notice that it returns immediately from the line: comSocket = new Socket("192.168.0.1",1531); This should indicate to me that a connection is made.
If you follow me so far... I should also say that if I shut the server down, the client resets by closing the connection and opening a new one. This time the comSocket = new Socket("192.168.0.1",1531) does not block as it should and the execution keeps going. This is obviously wrong. I think it is a resource release problem but why? With Winsock you can solve this problem with this line of code:
int so_reuseaddr = TRUE;
setsockopt(networkData->socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&so_reuseaddr,sizeof(so_reuseaddr));
Can you do something similar with Android or do you have to? Thank you for your help!
According to the javadoc the connection is established once you call the constructor.
Socket(InetAddress address, int port)
Creates a stream socket and connects it to the specified port number at the specified IP address.
When you press the home button, your app goes in background but it does not get killed immediately, so your comSocket might be not null when you get back to your application. In that case you are not calling the constructor again, thus you are not reconnecting to the server. What you should do is
if(comSocket == null){
comSocket = new Socket("192.168.0.1",1531);
}else{
comSocket.connect(new InetSocketAddress("192.168.0.1",1531));
}
(and please please place the curly brackets :-) )
Something to keep in mind is that the isConnected() method isn't very reliable for detecting when the remote side has closed the connection, (here is an example).
You have to figure this out by reading or writing on the associated Input/Output Streams.
Try using PrintWriter.checkError(), which will return true as soon as the client can no longer connect to the server.
I was trying to use SocketServer to setup a server
int i =1, PORT = 6666;
ServerSocket server;
Socket client;
try {
server = new ServerSocket(6666);
for(;;){
client = server.accept();//fail in here
textView.setText("server accept..." + i);
//new MyHttpServer(client, i, PORT).start();
i++;
}
} catch (IOException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
textView.setText("Fail...");
}
However, the app always stops in server.accept(). I have already add internet permission for this app. I don't know why?
Update:
I have found the reason. It is because thread cannot start from an Active instance. I was putted server.accept() in onStart without a thread. Now I open a new Runnable for it, then fixed
There could be multiple reasons why your application can not start the server. My initial guess would be that you are trying to run the code on an emulator or a device and you already have some other application listening on that port.
You must check/provide the logcat trace in order to get to the cause of the error.
I think so your app will wait for client with port 6666.
server.accept();// return socket
Above code will return socket if client is available.For more details and clearity you can refer these links::
http://www.happygeek.in/socket-programming-in-android
http://www.edumobile.org/android/android-development/socket-programming/