When I try to run a test composed of an echo server and an android client with the following code, I always get the exception msg "socket is closed". This code can simply send msg to server, and receive msg from server, but if you want to do both at the same time, it just doesn't work... I am very curious why it will lead to this kind of problem, and how should I fix it if I want it to be able to first send msg to echo server
and then receive msg from echo server?
// Server IP address
InetAddress serverIp;
// try to connect Server
try {
// set up server IP address
serverIp = InetAddress.getByName("192.168.17.1");
// set up port
int serverPort=12345;
// initiate socket connection
Socket clientSocket=new Socket(serverIp,serverPort);
BufferedOutputStream out = new BufferedOutputStream(clientSocket.getOutputStream());
out.write("Send From Android1111, stitch ".getBytes());
out.flush();
//wait to receive Server's msg
BufferedReader br =new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
total.toString();*/
// Display received msg with Toast
Toast.makeText(getApplicationContext(), br.readLine(), Toast.LENGTH_SHORT ).show();
//close connection
clientSocket.close();
// out.close();
// out = null;
} catch (IOException e) {
// display exception with Toast
Toast.makeText(getApplicationContext(),e.toString(), Toast.LENGTH_SHORT).show();
}
unfortunately, it still doesn't work ...I followed your instruction and modify the code to:
// set up Server IP address
serverIp = InetAddress.getByName("192.168.2.2");
// set up Server port
int serverPort=12345;
// initiate socket connection
Socket clientSocket=new Socket(serverIp,serverPort);
// open input and output stream
OutputStream out = clientSocket.getOutputStream();
InputStream in = clientSocket.getInputStream();
//send msg
out.write("Send From Android1111, bitch ".getBytes());
// receive msg from server
byte[] buffer = new byte[in.available()];
in.read(buffer);
String rMsg = new String(buffer);
Toast.makeText(getApplicationContext(), rMsg, Toast.LENGTH_LONG ).show();
//close input and output stream
in.close();
out.close();
//關閉連線
clientSocket.close();
} catch (IOException e) {
// 出錯後顯示錯誤訊息Toast
Toast.makeText(getApplicationContext(),e.toString(), Toast.LENGTH_SHORT).show();
}
for helper's convenience, here's the python written code for server part:
# Practice Echo Server Program written in Python
import socket
# host = '' means it binds to any available interface
host = ''
port = 12345
# socket() function returns a socket object whose methods implement the various socket system calls.
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# Bind the socket to address.
s.bind((host,port))
# Listen for connections made to the socket. The backlog argument specifies
# the maximum number of queued connections and should be at least 0;
# the maximum value is system-dependent (usually 5), the minimum value is forced to 0.
s.listen(5)
# Accept a connection. The socket must be bound to an address and listening for
# connections. The return value is a pair (conn, address) where conn is a new socket
# object usable to send and receive data on the connection, and address is the address
# bound to the socket on the other end of the connection.
conn, addr = s.accept()
print 'Connected by', addr
# Receive data from the socket. The return value is a string representing the data received.
# The maximum amount of data to be received at once is specified by bufsize. See the Unix
# manual page recv(2) for the meaning of the optional argument flags; it defaults to zero.
# Note For best match with hardware and network realities, the value of bufsize should be
# a relatively small power of 2, for example, 4096.
while 1:
data = conn.recv(1024)
if not data: break
print 'received data is : ', repr(data)
conn.send(data)
conn.close()
I assume you are doing the right things in the wrong order. May be the server is too fast and when you are trying to read the response it is already received and gone.
Following the rules presented in the tutorial Reading from and Writing to a Socket
Open a socket
Open an input stream and output stream to the socket.
Read from and write to the stream according to the server's protocol.
Close the streams.
Close the socket.
Do you see the difference? First open Input and Output stream and then start sending your request.
I am sure that if you stick to this order it will work.
I had a similar issue, solved it by editing the gradle.properties file to allow for proxy connections. I added the foregoing lines as explained on https://github.com/facebook/react-native/issues/2726 by Nadeem Shaik
systemProp.http.proxyHost=proxyHost
systemProp.http.proxyPort=proxyPort
systemProp.https.proxyHost=proxyHost
systemProp.https.proxyPort=proxyPort
Your application needs INTERNET permission in your AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET"/>
Related
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!
sorry for my bad english. I have to send and receive data from phone to radio using bluetooth pan interface on android. This is the code I've implemented to send, I've made it into the function DoInBackground() of AsyncTask:
try
{
ds = new DatagramSocket();
byte buf[] = "Ciao".getBytes();
DatagramPacket msg = new DatagramPacket(buf, buf.length, InetAddress.getByName(add), p);
ds.send(msg);
}
and it works perfectly. Now I have to wait 100 seconds the answer of the radio. I decide to implement it with this code:
try
{
ds.setSoTimeout(10000);
while(true)
{
try
{
ds.receive(dp);
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
catch (IOException e)
{
}
but there are three questions:
1. I need to receive the packet at 192.168.11.2 and 1234 port, but when I declared datagramsocket I set it void, because if i put port and address, send code doesn't work;
2. How can I manage the packet I've received by the radio? I don't need to use address and port bytes;
3. Why have I put the timeout before the loop?
Thank you for the answers.
1) Create the datagram socket with just the port number you are after. DatagramSocket(p);
2) You have a DatagramPacket with a bytebuffer of the size of the response and the length of the response i.e:
int responseLength = 1024;
byte[] responseData = new byte[responseLength];
DatagramPacket response = new DatagramPacket(responseData, responseLength);
After receiving into this datagram packet you need to convert it into same object that it was sent as. Something like this maybe:
String s = new String(response.getData());
3) The setSoTimeout doesn't cause the message to wait for 100s, it is just saying that after 100s if nothing has been read in by the receive() then it will timeout. This only needs to be set once per connection, setting this multiple times during the loop shouldn't be done.
Hope this helps
I am trying to send data from my Android phone to my home-server by using sockets. My server runs Linux so I used Perl to code the script for my server. The connection works fine and I can send data to my client running on the phone.
Problem is, when I send something (first try was a simple string) to the server, I don't receive anything at the servers side. Everything works fine if I use telnet to send a string to the server.
I am sitting here for some time now and I looked if there was a similar question to mine and could not find any in which the problem is discussed for Android to Perl-script. Here is my code for the Android app:
try {
Socket socket = new Socket("192.168.178.22", 22222);
Statusinformation("connection with server succeed");
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Statusinformation(input.readLine());
OutputStream outstream =socket.getOutputStream();
PrintWriter out = new PrintWriter(outstream);
out.println("This is a test message from client on phone!\n");
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
Statusinformation("connection unsucsessfull");
e.printStackTrace();
}
on my phone I receive this if i execute the above code:
connection with server succeed!
and on the server side I'm using this code to receive the string from socket clients:
use IO::Socket;
my $server = IO::Socket::INET -> new(
Proto => 'tcp',
LocalPort => 22222,
Listen => SOMAXCONN,
);
print "Server started..\n";
while (1) {
next unless my $conect = $server -> accept();
my $childconection = fork;
if ($childconection == 0) {
handle_connection($conect);
}
}
sub handle_connection
{
my $sock = shift;
my $client_message="";
my $client_addr = $sock -> peerhost;
print "connection: $client_addr connected\n";
print $sock "hi $client_addr, you are connected!\n";
while (1) {
open (Tempfile, '>>tempfile.txt');
while ($client_message = <$sock>) {
print Tempfile $client_message;
print $client_message;
}
close (Tempfile);
}
close($sock);
exit(0);
}
ok now I am a little ashamed.
I solved the problem by adding:
out.flush();
the flush() method assures that all pending data is send to the target and flushs the target.
Im trying to send a command through telnet to my computer which then sends the command to a serial port, when using telnet using
adb shell
$telnet 172.20.104.203 5334
$h
it returns the data from the command h, how ever when I try to do this using android it connects to the socket, I can see this on the computer, it sends the command but then as soon as it logs that it has sent it hangs and comes up with "Application not responding" and it has wait or force close and if I wait it just stays the same.
This is my code for the telnet part
private static final int TCP_SERVER_PORT = 5334;
private void runTcpClient() {
try {
Socket s = new Socket("172.20.104.203", TCP_SERVER_PORT);
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
//send output msg
String outMsg = "$getPos";
out.write(outMsg);
out.flush();
Log.i("TcpClient", "sent: " + outMsg);
//accept server response
String inMsg = in.readLine() + System.getProperty("line.separator");
Log.i("TcpClient", "received: " + inMsg);
//close connection
s.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
It logs the send, but it never logs the receive, I thought it might be something to do with the amount of data being received so I just sent
$getPos
instead but it still hangs.
Any one know what could be happening?
I'm not familiar with the particulars of the platform, but its unlikely that a readline will work on a socket/tcp stream, or if it works, it will work unreliably. Data coming in from a socket is not necessarily organized into 'lines', but instead packets of a particular size. A 'read' performed on a socket will return some number of bytes.
The client doing such reads needs to read each packet, buffer them until it receives an agreed-upon 'end of data' marker. The marker agreed-upon is determined by protocol.
You've shown us the client side of your code. Do you have a corresponding server side?
From what you have here, my guess is that your client code is waiting patiently for an 'end of line' that for some reason, will never come. OR there's something wrong at the server end and the server isn't sending any data to the client.
I've been having an issue with data integrity using an RFCOMM socket over Bluetooth in Android. I don't have any issues connecting, but the data I receive is garbled and not the same as the data that is sent. The data is sent by an RS232 device over a Bluetooth adapter, which the phone connects to. There isn't a problem with the adapter as the data is properly received if I connect with a laptop.
My Bluetooth connection is handled based off of the BluetoothChat sample application found at the Android developer site (http://developer.android.com/resources/samples/BluetoothChat/index.html), with no changes. The data being sent is plain text and control characters (which are stripped out before display to the user). The specific problem I have is that some of the text is missing, some of it is repeated, etc.
The funny thing is if I connect to a computer with a terminal app and type in there, the data is transmitted fine. Additionally, if I connect to the device using the GetBlue app the data is received fine.
So I guess the issue is what does GetBlue possibly do different to handle its Bluetooth data transfer, or is there another way receive Bluetooth data over an RFCOMM socket on Android?
The fix for the solution was to create the string in the connected thread, directly after calling read() on the InputStream, and then passing the string back to the main thread for display. For whatever reason, passing the byte array between threads led to significant repetition and data loss.
Modified run() code:
public void run() {
byte[] buffer = new byte[256]; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
String readMessage = new String(buffer, 0, bytes);
// Send the obtained bytes to the UI Activity
mHandler.obtainMessage(MESSAGE_READ, bytes, -1, readMessage)
.sendToTarget();
} catch (IOException e) {
break;
}
}
}
And the handler reception:
case MESSAGE_READ:
// Read in string from message, display to mainText for user
String readMessage = (String) msg.obj;
if (msg.arg1 > 0) {
mainText.append(readMessage);
}
This error is because the object reference is passed to the UI, If you copy the byte array(buffer) to another byte array it works.