i am working on an app in android studio and basiclly i need that whenever i clicked a specific button it will create a connection between the java client and python server.
I first checked when u enter the page\activity of the specific button if there is a wifi connection in the phone.
It works fine. then i tried to do this and it didnt work (Important to say that the current code make my phone and my app crash and stop)
simple server:
HOST = '192.168.1.21'
PORT = 9000
def main():
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((HOST, PORT))
server_socket.listen(10)
client_socket, client_address = server_socket.accept()
print 'Connect with ' + client_address[0]
data = client_socket.recv(1024)
print "data :"
print data
print " end"
if data == HOST+"/n":
print 'hi'
else:
i = 0
while i < 15:
print i
i += 1
client_socket.close()
server_socket.close()
if __name__ == '__main__':
main()
this is just to check a connection. it might look strange because of the host +/n in the if . i recently chenged it because i am new to java and dont know how the data is sent. but that is not the problem rn.
public void ButtonClicked(View view) {
EditText editText = findViewById(R.id.edit_text);
final String ip = editText.getText().toString();
Toast.makeText(this, ip, Toast.LENGTH_SHORT).show();
try {
InetAddress host = InetAddress.getByName(ip);
final Client client = new Client(host, 9000);
new Thread(new Runnable() {
public void run() {
try {
client.send(ip);
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
client.send(ip);
}
catch (IOException e) {
System.out.println("Caught Exception: " + e.toString());
}
i read that in android studio 3.0 u need to create a thread when u send data.
the client class that u see here :
public class Client
{
private Socket socket = null;
private BufferedReader reader = null;
private BufferedWriter writer = null;
public Client(InetAddress address, int port) throws IOException
{
socket = new Socket(address, port);
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
}
public void send(String msg) throws IOException
{
writer.write(msg, 0, msg.length());
writer.flush();
}
public String recv() throws IOException
{
return reader.readLine();
}
}
it might be just a simple thing that i dont know of but those are the codes and i cant connect to the server. i figured out that the server works fine because if im connecting from the phone to 192.168.1.21 on the net i receive the connection and it does thw little while.
ty for the help - i would like to get the simplest fixes because im new to java.(sorry if there where grammer\ spelling mistakes)
Edit- logcat for the crash
At the end of your log it says NetworkOnMainThread. In your code there is a line client.send(ip) below your seperate thread which is executed at the main thread.
Related
I created 2 Java programs with sockets in it. I want the client to send continuous data to the server. But after the message sent to the server, the client keeps sending 'null' value to the server (it happens when I close the socket in client program).
Here is my codes:
import ...
public class MainClient {
private Socket serverSock;
private PrintStream clientOutput;
public static void main(String[] args) {
MainClient client = new MainClient();
client.runClient();
}
public void runClient() {
try {
serverSock = new Socket("127.0.0.1",8282);
clientOutput = new PrintStream(serverSock.getOutputStream());
clientOutput.println("Hello, I'm Connected.");
for (int i=0;i<5;i++) {
clientOutput.println(i + "");
clientOutput.flush();
}
} catch (IOException e) {
e.printStackTrace();
}finally {
// try {
// serverSock.close(); It will keeps sending 'null' data to the server if I use this line.
// } catch (IOException e) {
// e.printStackTrace();
// }
}
}
}
The Server Side:
public class MainServer {
private ServerSocket serverSocket;
private int listenPort = 8282;
private InputStream inps;
private Socket clientSocket;
private BufferedReader clientInput;
private MainServer() {
String clientMsg = "";
try {
serverSocket = new ServerSocket(listenPort);
System.out.println("Server is Listening on " + listenPort);
clientSocket = serverSocket.accept();
clientInput = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
while(clientSocket.isConnected()) {
clientMsg = clientInput.readLine();
System.out.println("Client : " + clientMsg);
}
}catch(IOException ex) {
ex.printStackTrace();
}finally {
try {
clientSocket.close();
} catch (IOException e) {}
}
}
public static void main(String[] args) {
new MainServer();
}
}
I tried to close the OutputStream on the Client side with clientOutput.close(); but it sends nulls to the server after it sends the 0-4 loop.
To make it stop and avoid the client sends null data, i should not insert the serverSock.close(); on the Client, but it will returns SocketException. I wanted the client to send 'Closed' message after its done.
Summary, the output on the server is:
Client: 0
Client: 1
Client: 2
Client: 3
Client: 4
Client: null
Client: null
//And so on..
I think there is something missing on the Client Program, i guess?
Thank you for the help :)
As the comment noted, the client is not sending a null value.
The isConnected() method does not do what you think it does, namely it does not tell you if the socket is currently "connected" to its peer, at least in the way you think it should. isConnected() becomes true as soon as the socket transitions into the connected state, and stays true thereafter, even after the socket is shutdown. See this discussion and others on stackoverflow.
The correct way to determine if the peer has shutdown the connection is to attempt to read from the socket and then examine the result for evidence of closure. Please read the Javadocs for the method you are using, they will tell you what the various return values mean. For the BufferedReader.readLine() method, it says:
Returns:
A String containing the contents of the line, not including
any line-termination characters, or null if the end of the stream has
been reached
Throws:
IOException - If an I/O error occurs
Thus you need to check for a null return value to detect a normal socket closure, and if you receive an IOException that indicates some kind of network anomaly.
Your MainClient() have no problem.
clientSocket.isConnected() function in MainServer() always check the status of the client and which results an infinite loop, so after the message 'client:4', clientInput.readLine() should return 'null'.
So instead of checking the client socket is connected or not you can check the client socket is closed or not using function 'clientSocket.isClosed()'.
replace the while loop in MainServer() with below code,
while(!clientSocket.isClosed()) {
clientMsg = clientInput.readLine();
System.out.println("Client : " + clientMsg);
if(clientMsg.equals("Closed")){
clientSocket.close();
// serverSocket.close();
}
}
this will help you to close the client socket at the time of receiving 'Closed' message from server and this avoid the infinite execution of while loop as well as null statement printing.
The code "serverSocket.close()" help you to close the server socket and you can use this at 'MainServer()' if you need to stop the port listening.
typically the code should be something similar
private MainServer() {
String clientMsg = "";
try {
serverSocket = new ServerSocket(listenPort);
System.out.println("Server is Listening on " + listenPort);
clientSocket = serverSocket.accept();
clientInput = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
while ((clientMsg = clientInput.readLine()) != null) {
if(isTerminationString(clientMsg)) {
break;
}
System.out.println("Client : " + clientMsg);
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
clientSocket.close();
} catch (IOException e) {
}
}
}
boolean isTerminationString(String msg) {
return msg.equals("DONE!");
}
where in isTerminationString you check if the msg is a termination msg, the communication protocol should be shared between the client and the server . i gave the example of sending
a DONE message, but it could more complex than that .
as closing the close method on the socket does not guarantee that the socket on the other part gets closed as well, using the isClosed method might not be effective and results in the same problem you have .
I am trying to open a socket inside a bukkit plugin so i could send data to it using php or node but instead of socket remaining open after one use it just closes and also server does not load before this happens what should i do i am out of ideas.
Main:
public class Main extends JavaPlugin {
public void onEnable() {
saveDefaultConfig();
getConfig().options().copyDefaults(true);
System.out.println("[INFO] Main class loaded.");
start();
}
public void start() {
SocketServer server = new SocketServer();
try {
server.start(getConfig().getInt("port"), getConfig().getString("socket-password"));
System.out.println("[INFO] Main successfully called start.");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Socket server class:
When called this should read information convert it into array check the first item in array and use it as auth code then array should be converted into string and used in Command executor class. This works fine but after one use this just closes
public class SocketServer {
private ServerSocket serverSocket;
private Socket clientSocket;
private PrintWriter out;
private BufferedReader in;
public void start(int port, String socketpwd) throws IOException {
System.out.println("[INFO] Socket server listening on: " + port);
serverSocket = new ServerSocket(port);
clientSocket = serverSocket.accept();
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
Boolean enabled = true;
try {
// Socket authentication
String message = in.readLine();
String suffix[] = message.split(" ");
System.out.println("Socket auth code used: "+ suffix[0]);
System.out.println("Socket pwd is: " + socketpwd);
if (socketpwd.equals(suffix[0])) {
out.println("Auth sucessfull!");
// do the following command from args here
String command = suffix[1];
int suffixL = suffix.length;
// add arguments to command
for (int i = 2; i < suffixL; i++) {
command = command + " " + suffix[i];
}
// call req exec
System.out.println("[INFO] Socket server contacted Request executor with: " + command);
RequestExecutor.executor(command);
enabled = false;
}
else {
out.println("Unrecognised auth code!");
}
} catch (NullPointerException e) {
System.out.println("Exception prevented!");
}
}
public void stop() throws IOException {
in.close();
out.close();
clientSocket.close();
serverSocket.close();
}
}
Other problem as i mentioned is that bukkit server does not fully load before one request has been made to this socket.
Thank you for your help.
First of all you shouldn't be running a socket like that on the main thread, typically you should be running this on an async task using the Bukkit scheduler.
Then once you open the socket you should create a while loop to continuously poll for a connection and handle the incoming data. Instead what you are doing is opening the socket, reading a line and then dropping the connection.
You want to be doing something similar to
while(true){
Socket socket = serverSocket.accept();
}
See this webpage for some more info.
I am writing a simple Java Socket Client that is able to connect to a socket and pass a certain request to the server. Pretty much what I am trying to do:
Java Client connects to socket sends request to server
Server processes request and sends back "starting"
Java Client waits for next progress update
Server sends "progress 10%"
Java Client receives the progress update and processes accordingly
Server sends progress update 20%... so on so forth
I do not want to constantly check if there is something in the input stream but rather have the client retrieve the data as soon as there is something pending and process it (on a background thread). I am fairly new to working with java and networking in general so I don't know much about implementing this.
Server code (python, running on a raspberry pi):
import SocketServer
from SocketServer import TCPServer, ThreadingMixIn, StreamRequestHandler
import sys
import time
import socket
# We mix with ThreadingMixIn to allow several simultaneous
# clients. Otherwise, a slow client may block everyone.
class ThreadingTCPServer(ThreadingMixIn, TCPServer):
pass
# StreamRequestHandler provides us with the rfile and wfile attributes
class RequestHandler(StreamRequestHandler):
def handle(self):
print str(self.client_address) + 'connected'
data = "foo"
while data != "":
data = self.rfile.readline()
print data
try:
self.wfile.write("foo\n")
except socket.error: # Client went away, do not take that data into account
data = ""
print 'Handler Exiting'
self.request.close()
def finish(self):
print 'Client Disconnected'
if __name__ == '__main__':
PORT = 80
ThreadingTCPServer.allow_reuse_address = True
server = ThreadingTCPServer(("", PORT), RequestHandler)
try:
server.serve_forever()
except KeyboardInterrupt:
print "\nServer Terminated"
Basically at the end of prototyping I will be implementing this into an Android app. If you were wondering I am planning on using this to run some home automation and some other things.
This is the current client code I am working with (from an example online and I modified it a little):
import java.lang.*;
import java.io.*;
import java.net.*;
public class ClientTest {
private Socket socket = null;
private BufferedReader reader = null;
private BufferedWriter writer = null;
public ClientTest(InetAddress address, int port) throws IOException {
socket = new Socket(address, port);
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
}
public void send(String msg) throws IOException {
writer.write(msg, 0, msg.length());
writer.flush();
}
public String recv() throws IOException {
return reader.readLine();
}
public static void main(String[] args) {
try {
InetAddress host = InetAddress.getByName("192.168.1.15");
ClientTest client = new ClientTest(host, 80);
//ClientTest client2 = new ClientTest(host, 9999);
for (int i = 1; i <= 1000; i++) {
client.send("bar " + i + "\n");
String response = client.recv();
System.out.println("" + i + ": " + response);
try {
Thread.sleep(15);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//client2.send("Client2\n");
}
client.socket.close();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//client2.socket.close();
} catch (IOException e) {
System.out.println("Caught Exception: " + e.toString());
}
}
}
Instead of String response = client.recv(); I want to have this function automatically called whenever the server sends back a request and have the message processed in the background. (I think it is somewhere along the lines of a callback function)
All answers appreciated!
I would like to open a TCP connection to send data to an ip address in an android application. Every socket programming article/thread I find shows both client and server side code (often the chat program). Is it possible to just have the client code running on an android device and send arbitrary data to, for example, google's IP address? Right now I am using the code from this thread (highest upvoted answer) Android Client socket , how to read data? in a class that extends AsynchTask like this:
public class InternetTask extends AsyncTask<Void, Integer, Void> {
public static final int BUFFER_SIZE = 2048;
private Socket socket = null;
private PrintWriter out = null;
private BufferedReader in = null;
private int port = 80;
private String host = null;
private static final String TAG="sure2015test";
public InternetTask(String host,int port) {
this.host=host;
this.port=port;
}
#Override
protected Void doInBackground(Void... args) {
connectWithServer();
Log.i(TAG, "Connected");
sendDataWithString("hello");
Log.i(TAG, "Sent data");
String response=receiveDataFromServer();
Log.i(TAG,response);
disConnectWithServer();
return null;
}
private void connectWithServer() {
try {
if (socket == null) {
socket = new Socket(this.host, this.port);
out = new PrintWriter(socket.getOutputStream());
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
} catch (IOException e) {
Log.i(TAG,"IO Exeception");
e.printStackTrace();
}
}
private void disConnectWithServer() {
if (socket != null) {
if (socket.isConnected()) {
try {
in.close();
out.close();
socket.close();
} catch (IOException e) {
Log.i(TAG,"IO exception disconnecting");
e.printStackTrace();
}
}
}
}
public void sendDataWithString(String message) {
if (message != null) {
connectWithServer();
out.write(message);
out.flush();
}
}
public String receiveDataFromServer() {
try {
String message = "";
int charsRead = 0;
char[] buffer = new char[BUFFER_SIZE];
Log.i(TAG,"Message before: "+message);
while ((charsRead = in.read(buffer)) != -1) {
message += new String(buffer).substring(0, charsRead);
Log.i(TAG,message);
}
Log.i(TAG,"Message after: "+message);
disConnectWithServer(); // disconnect server
return message;
} catch (IOException e) {
Log.i(TAG,"IO Error in receiving message");
return "Error receiving response: " + e.getMessage();
}
}
}
And my onCreate method in MainActivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
InternetTask task=new InternetTask("74.125.226.159",80);
task.execute();
}
When I run this I get this in the logs:
05-16 00:01:04.368 622-637/? I/sure2015test﹕ Connected
05-16 00:01:04.369 622-637/? I/sure2015test﹕ Sent data
05-16 00:01:04.369 622-637/? I/sure2015test﹕ Message before:
05-16 00:03:04.405 622-637/com.example.connorstein.sockethelloworld I/sure2015test﹕ Message after:
So there were no exceptions when opening a socket on port 80 with the IP of google and no exceptions sending or receiving the data. It looks like I just have no response. Is this expected because the data I sent ("hello") is meaningless? I would think that at least I would get a response saying invalid request or something like that. I also tried sending "GET / HTTP/1.0", but also no response.
Google is responding blank because you aren't sending it a proper HTTP request. Mimic the request of a normal web browser, and you will get a response. HTTP is a protocol built on top of TCP. You need to follow the protocol to get anything useful out of servers.
Example minimal browser header that gets a response:
GET / HTTP/1.1\r\nUser-Agent: curl/7.37.1\r\nHost: www.google.com\r\nAccept: */*\r\n\r\n
Instead of using a web server, consider using an SSH server. An SSH server will send something like...
SSH-2.0-OpenSSH_5.3\r\n
...when you connect. A server that always responds is a lot easier to troubleshoot client code. Note that you might make a sysadmin mad constantly connecting to their ssh server. You may want to set up your own to test against.
I am trying to communicate from php to java using sockets. I have the following java code:
private static ServerSocket socket;
private static Socket connection;
private static String command = new String();
private static String responseStr = new String();
private static int port = 2500;
public static void main(String args[]) {
System.out.println("Server is running.");
try {
socket = new ServerSocket(port);
while (true) {
connection = socket.accept();
InputStreamReader inputStream = new InputStreamReader(connection.getInputStream());
DataOutputStream response = new DataOutputStream(connection.getOutputStream());
BufferedReader input = new BufferedReader(inputStream);
command = input.readLine();
response.writeBytes(responseStr);
response.flush();
}
} catch (IOException e) {
System.out.println("Fail!: " + e.toString());
}
}
I have the following PHP code:
<?php
$socket = stream_socket_server("tcp://192.168.0.10:2500", $errno, $errstr);
if (!$socket) {
echo "$errstr ($errno)<br />\n";
} else {
while ($conn = stream_socket_accept($socket)) {
fwrite($conn, 'The local time is ' . date('n/j/Y g:i a') . "\n");
fclose($conn);
}
fclose($socket);
}
I start the java app, which starts fine, When I run the php, I get the following error:
An attempt was made to access a socket in a way forbidden by its access permissions. (0)
I have searched Google and have tried all the solutions I could find although nothing has worked. I have restarted both machines and disabled the firewall, neither worked.
I am not sure where to go from here.
[update from comment:]
192.168.0.10 is the machine with the java app and web server on it. I am connecting from another machine 192.168.0.7
You can only can create a socket on the machine were the code is running on.
So if the PHP code is run on 192.168.0.7, then do:
$socket = stream_socket_server("tcp://192.168.0.7:2500", $errno, $errstr);