I have been trying to make a client project on Android Studio that will connect to a server that I made in Python (Pycharm). As for the IP used, I entered at the server the local host and in the client the IPV4 of the computer's server.
The debugging was made through the phone itself and not the emulator.
When I tried running the code and connect to the server through out the ipv4 with the same port, I got connection timed out.
At the moment, the debugger is stuck on the client class while trying to get a message from the server, the - "while ((bytesRead = inputStream.read(buffer))" - line while on the server, the code did not recieve any message from the client and thus its stuck on receiving.
How do I solve this issue?
Client code: - Where the connection occurs
public class RequestAndAnswer extends AsyncTask<Void, Void, Void> {
private String dstAddress,result1;
private int dstPort;
private String response = "";
private String out;
RequestAndAnswer(String output)
{
dstAddress = "1.5.0.66"; //fake ipv4
out= output;
dstPort= 8886;
}
#Override
protected Void doInBackground(Void... arg0) {
Socket socket = null;
try {
socket = new Socket(dstAddress, dstPort);
//send out to server
DataOutputStream DOS = new DataOutputStream(socket.getOutputStream());
DOS.writeUTF(out);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(1024);
byte[] buffer = new byte[1024];
int bytesRead;
InputStream inputStream = socket.getInputStream();
while ((bytesRead = inputStream.read(buffer)) != -1) {
byteArrayOutputStream.write(buffer, 0, bytesRead);
response += byteArrayOutputStream.toString("UTF-8");
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "UnknownHostException: " + e.toString();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "IOException: " + e.toString();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return null;
}
The main code:
public void onClick(View v)
{
if(v == loginButton)
{
String userNameString = userName.getText().toString();
String passwordString = password.getText().toString();
String output ="100"+
intToString(userNameString.length())
+userNameString
+ intToString(passwordString.length())
+passwordString;
RequestAndAnswer myClient = new RequestAndAnswer(output);
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB)
myClient.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else
myClient.execute();
String answer="";
do {
answer = myClient.getResult(); /**In order to make sure that I
will get my response after the
communication started between
the server and the client **/
}
while(answer.matches(""));
if(answer.matches("1100"))
{
Intent i = new Intent(this,Computer_choosing_selection_activity.class);
i.putExtra("username",userNameString);
startActivity(i);
finish();
}
else if(answer.matches("1101"))
{
String error = "The username and password do not match";
errorText.setTextColor(Color.RED);
errorText.setText(error);
}
else
{
String error = "Could not connect";
errorText.setTextColor(Color.RED);
errorText.setText(error);
}
}
The AndroidManifest.XML includes the following lines -
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
The server code: - In python
import socket
import sys
HOST = '127.0.0.1' # Symbolic name, meaning all available interfaces
PORT = 8886 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
#Bind socket to local host and port
try:
s.bind((HOST, PORT))
except socket.error as msg:
print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
print 'Socket bind complete'
#Start listening on socket
s.listen(10)
print 'Socket now listening'
#now keep talking with the client
while 1:
#wait to accept a connection - blocking call
conn, addr = s.accept()
print 'Connected with ' + addr[0] + ':' + str(addr[1])
data = s.recv(1024)
number = data.substr(0,3)
if(number == "100"):
data = data[4:]
len=data[0:3]
data=data[2:]
name = data[:int(len)]
data = data[int(len):]
len=data[0:3]
data=data[2:]
password = data[:int(len)]
if((name == "Tod") and (password == "Aa123456")):
conn.send("1100")
else:
conn.send("1101")
s.close()
EDIT:
I changed in the server the address to the IPV4 instead of the local 127.0.0.1 and I managed to connect although it gave me the following error before hand
"Socket.error: [Errno 10057] request to send or receive data was denied because the component is not connected to the socket and provided an address (when sending data socket unit via a call to sendto)"
after this message I got an output of"connected" and the program shut down.
Related
the question is totally rewritten since I have understood that previously it was really unclear.
I have created a Java Socket server with threads to accept multiple connection in order to handle php tcp requests.
The java server just for the testing purposes it reverse the string supplied from php.
Java server is hosted on a ubuntu server and the php is located on another machine.
The java server shows that php client is connected, but the php is not loading and the string is not sent.
From the codes given below what could be the mistake?
UPDATE
the problem is the received string from the Java server. I have checked with debugger and the BufferedReader is full of '\u0000' and server stops responding. The rest code and communication is working perfect.
How I can avoid those null characters or decode the string correct?
ReverseServer
import java.io.*;
import java.net.*;
public class ReverseServer {
public static void main(String[] args) {
int port = 10007;
try (ServerSocket serverSocket = new ServerSocket(port)) {
System.out.println("Server is listening on port " + port);
while (true) {
Socket socket = serverSocket.accept();
System.out.println("New client connected");
new ServerThread(socket).start();
}
} catch (IOException ex) {
System.out.println("Server exception: " + ex.getMessage());
ex.printStackTrace();
}
}
}
ServerThread
import java.io.*;
import java.net.*;
public class ServerThread extends Thread {
private Socket socket;
public ServerThread(Socket socket) {
this.socket = socket;
}
public void run() {
try {
InputStream input = socket.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
OutputStream output = socket.getOutputStream();
PrintWriter writer = new PrintWriter(output, true);
String text;
do {
text = reader.readLine();
String reverseText = new StringBuilder(text).reverse().toString();
writer.println("Server: " + reverseText);
} while (!text.equals("bye"));
socket.close();
} catch (IOException ex) {
System.out.println("Server exception: " + ex.getMessage());
ex.printStackTrace();
}
}
}
PHP client
<?php
// websocket connection test
$host = "ip_of_server";
$port = 10007;
$message = "Hello";
echo "Message To server :".$message;
$socket = socket_create(AF_INET, SOCK_STREAM, getprotobyname('TCP'));
$result = socket_connect($socket, $host, $port);
if ($result) {
// send string to server
socket_write($socket, $message, strlen($message)) or die("Could not send data to server\n");
// get server response
$result = socket_read($socket, 1024) or die("Could not read server response\n");
echo "Reply From Server :" . $result;
}
socket_close($socket);
I am trying to read a line, but on the string given on the php client didn't had the carriage return symbol "\r".
Once I have put this on the string it works as expected.
I am making a Server Client System from which the client(android user) send message to the server(python socket). i have tried this at own level but it does not work..Code is shown Below.
Any Help is Aprecated
Socket Server Side
import socket
import threading
import pyaudio
PORT = 7800
HEADER = 64
FORMAT= "utf-8 "
DISCONNECT_MSG="!DISCONNECTED"
SERVER=socket.gethostbyname(socket.gethostname())
ADDR = (SERVER,PORT)
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind(ADDR)
connection_list = []
def handle_clinet(conn,addr):
print(f"[NEW CONNECTION]{addr} Connected")
CONNECTED = True
while CONNECTED:
msg_length = conn.recv(HEADER).decode(FORMAT)
if msg_length:
msg_length=int(msg_length)
msg = conn.recv(msg_length).decode(FORMAT)
if msg == DISCONNECT_MSG:
CONNECTED = False
if msg == "Disconnect":
conn.close()
CONNECTED = False
print("Dissconnected From the User...")
else:
print(msg)
def start():
server.listen()
while True:
conn,addr = server.accept()
thread = threading.Thread(target=handle_clinet,args=(conn,addr))
thread.start()
print(f"[ACTIVE CONNECTIONS] {threading.active_count() -1}")
connection_list.append(addr)
print(connection_list)
print("[Starting] the server...")
start()
Client Side
public class send extends AsyncTask<String,Void,Void> {
String message;
Socket socket;
PrintWriter pw ;
String ip = "198.168.**.***";
#Override
protected Void doInBackground(String... strings) {
try{
socket = new Socket(ip,7800);
pw= new PrintWriter(socket.getOutputStream());
pw.write("Hello World");
pw.flush();
pw.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
to send message i use
val sendcode = send()
message=iptextview.text.toString()
sendcode.execute(message)
If any other Suggestion on topic is also apricated.
This question already has answers here:
Server not reading client messages
(1 answer)
Reading data from a socket java
(1 answer)
Socket reading through buffered reader, not picking up on line
(2 answers)
Java - Socket not reading until client disconnects?
(4 answers)
Java ServerSocket won't send or receive messages from client
(1 answer)
Closed 3 years ago.
I have a client server program where the serverscoket will accept a connection form the client, and the client can receive messages from the server, but not vice versa.
The Client:
public class ChatClient {
private final String serverName;
private final int serverPort;
private Socket socket;
private OutputStream serverOut;
private InputStream serverIn;
private BufferedReader bufferedInputStream;
//private ArrayList<UserStatusListener> userListners = new ArrayList<UserStatusListener>();
private ChatClient(String serverName, int serverPort) {
super();
this.serverName = serverName;
this.serverPort = serverPort;
}
public static void main(String[] args) throws IOException {
ChatClient client = new ChatClient("localhost", 8818);
// Make sure serverboot is running and listenig first
if (! client.connect()) {
System.out.println("Connection Failed. Is ServerBoot running/listening?");
}else {
System.out.println("Connection succesful");
client.login("guest");
}
}
private boolean connect() {
// TODO Auto-generated method stub
try {
this.socket = new Socket(serverName, serverPort);
// get streams
this.serverOut = socket.getOutputStream();
this.serverIn = socket.getInputStream();
this.bufferedInputStream = new BufferedReader(new InputStreamReader(serverIn));
return true;
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
return false;
}
}
private void login (String login) throws IOException {
// send login to server
try {
String serverResponse = bufferedInputStream.readLine();
System.out.println("Server response: " + serverResponse);
while (bufferedInputStream.readLine() != null) {
System.out.println(bufferedInputStream.readLine());
}
String send = "Login : " + login;
serverOut.write(send.getBytes());
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
Snippets form the server:
try {
ServerSocket serverSocket = new ServerSocket(serverPortNumber);
while (true) {
// Listen for incoming connections and craete connection with accept
System.out.println("Waiting for client connection.... on localhost port " + serverPortNumber
+ ". \n Client connect via netcat localhost 8818");
Socket clientSocket = serverSocket.accept();// returns a client Socket object
System.out.println("Conenction established with " + clientSocket);
// Each new connection will be handled on a new thread and can run concurrenlty
ManageMultipleConnections multipleConnections = new ManageMultipleConnections(this, clientSocket);
clientList.add(multipleConnections);
multipleConnections.start();
}
// get client socket input out streams
clientInput = clientSocket.getInputStream();
clientoutput = clientSocket.getOutputStream();
// write to the client socket
clientoutput.write((message).getBytes());
// attempt to read form the client but we never receive any messages
BufferedReader br = new BufferedReader(new InputStreamReader(clientInput, ENCODING));
String inputLine;
String returnMessage;
String msg = br.readLine();
System.out.println(br.readLine());
while ((inputLine = br.readLine()) != null && inputLine != "") {....do stuff
Any input appreciated.
After a week of trying just about ever possible solution out there I found that appending a return carriage and a new line character to every message the client sent to the server via an outputtsteam did the trick.
private static final String CRLF = "\r\n"; // newline
try {
outputStream.write((text + CRLF).getBytes());
outputStream.flush();
} catch (IOException e) {
e.printstacktrace();
}
I am not sure why this worked so anyone out there that could shed light on this would be great. I am using java swing in eclipse on Windows 10 OS.
I have tried everything to get this to work. Basically I have an Android App which receives data from a Python based Server on a local network connection. I can receive Data no problem. However when I attempt to send data back the App crashes and the Python server receives blank data. I have tried several different approaches but non have worked. Here is the Python method I have written to receive the message:
def checkReply(self):
reply = "no reply yet"
self.conn.settimeout(1)
try:
test = self.conn.recv(1024)
except:
self.conn.timeout;
print("I failed to hear this") #Debug to help see if I have heard an incomming message
try:
data = test.decode()
reply = data
except:
print("I failed to decode this") #Debug to help see if I could not decode an incomming message
print(reply)
self.conn.settimeout(0)
My client on my Android application looks like this:
public class Client extends AsyncTask<Void, Void, Void> {
String dstAddress;
int dstPort;
String response = "No data has been sent yet";
TextView textResponse;
Socket socket = null;
Client(String addr, int port, TextView textResponse) {
dstAddress = addr;
dstPort = port;
this.textResponse = textResponse;
}
#Override
protected Void doInBackground(Void... arg0) {
Socket socket = null;
try {
socket = new Socket(dstAddress, dstPort);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(
1024);
byte[] buffer = new byte[1024];
int bytesRead;
InputStream inputStream = socket.getInputStream();
/*
* notice: inputStream.read() will block if no data return
*/
while ((bytesRead = inputStream.read(buffer)) != -1) {
byteArrayOutputStream.write(buffer, 0, bytesRead);
response = byteArrayOutputStream.toString("Ascii");
}
byteArrayOutputStream.flush();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "UnknownHostException: " + e.toString();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "IOException: " + e.toString();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return null;
}
#Override
protected void onPostExecute(Void result) {
textResponse.setText(response);
super.onPostExecute(result);
}
protected String getSite(){
return response;
}
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
public void returnMsg(){
try (DataOutputStream outToClient = new DataOutputStream(socket.getOutputStream())) {
byte[] buf = "hello".getBytes("UTF-8");
outToClient.writeBytes("Test");
outToClient.flush();
} catch (IOException e) {}
}
}
I am having to test on a physical device so I have no log to trace the error message. Any help would be greatly appreciated. Thanks
I managed to solve the issue. I needed to flush the buffer before trying to send any data back via the socket
I'm developing an app that, at startup, uses SSDP to connect to a server and retrieve it's IP Address. The SSDP class was not developed by me so I'm open to any refactoring suggestions in there as well but for this question, I'm trying to implement the logic that will keep searching for the server using SSDP while avoiding any crashes or timeout exceptions from being thrown.
Currently, my presenter class uses a private AsyncTask class to get the response from the server(called MOTA or OTA station in the commenting):
private class SearchAction extends AsyncTask<Void,Void,String>{
Context context;
SearchAction(Context context){
this.context = context;
}
protected void onPreExecute(){
view.changeVisibility(true);
}
#Override
protected String doInBackground(Void... params) {
//Get IP Address from MOTA Station
SSDP ssdp = new SSDP();
String ip = ssdp.request();
Log.d(TAG,"IP Address is: "+ ip);
return ip;
}
#TargetApi(Build.VERSION_CODES.KITKAT)
protected void onPostExecute(String ip_address){
Log.d(TAG, "IP address is: " + ip_address);
if (Objects.equals(ip_address, "")) {
view.changeVisibility(false);
// TODO: give choice to user to enter IP address manually
}else {
//otherwise go to MainActivity directly
Intent intent = new Intent(context, Main2Activity.class);
intent.putExtra("IP", ip_address);
view.navigateToMainActivity(intent);
}
}
}
The SSDP class looks like so:
public class SSDP {
public String tag = "SSDP";
//m-search string for specific OTA board
private static final String query =
"M-SEARCH * HTTP/1.1\r\n" +
"HOST: 239.255.255.250:1900\r\n"+
"MAN: \"ssdp:discover\"\r\n"+
"MX: 1\r\n"+
"ST: urn:schemas-upnp-org:device:MediaServer:1\r\n"+ // Use for OTA Board
//"ST: ssdp:all\r\n"+ // Use this for all UPnP Devices
"\r\n";
private static final int port = 1900;
//ssdp to find IP address from server
public String request(){
//response is to contain the server response in String type
//initialize send data and receive data in bytes
String response="";
byte[] sendData = new byte[1024];
byte[] receiveData = new byte[1024];
//transfer m-search string in bytes
sendData = query.getBytes();
//wrap m-search data, multicast address and port number to the send package
DatagramPacket sendPacket = null;
try {
sendPacket = new DatagramPacket(sendData, sendData.length, InetAddress.getByName("239.255.255.250"), port);
} catch (UnknownHostException e) {
Log.d(tag,"Unknown Host Exception Thrown after creating DatagramPacket to send to server");
e.printStackTrace();
}
//create socket to transport data
DatagramSocket clientSocket = null;
try {
clientSocket = new DatagramSocket();
} catch (SocketException e) {
Log.d(tag, "Socket Exception thrown when creating socket to transport data");
e.printStackTrace();
}
//send out data
try {
if (clientSocket != null) {
//time out is important
clientSocket.setSoTimeout(10000);
clientSocket.send(sendPacket);
}
} catch (IOException e) {
Log.d(tag, "IOException thrown when sending data to socket");
e.printStackTrace();
}
// receive data
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
try {
if (clientSocket != null) {
clientSocket.receive(receivePacket);
}
} catch (IOException e) {
Log.d(tag,"IOException thrown when receiving data");
e.printStackTrace();
}
//the target package should not be empty
//try three times
for (int i =0; i<3; i++){
Log.d(tag,"Checking target package to see if its empty on iteration#: "+i);
response = new String(receivePacket.getData());
Log.d(tag,"Response contains: "+response);
if (response.contains("Location:")){
break;
}
}
String adress = "";
//filter IP address from "Location"
Matcher ma = Pattern.compile("Location: (.*)").matcher(response);
if (ma.find()){
adress+=ma.group(1);
adress = adress.split("/")[2].split(":")[0];
}
return adress;
}
}
My question is, how can I call request() repeatedly (or a specific part of request()) until I get a response from the server?
I used a Timer Task to perform the AsyncTask every 5 seconds.
private Runnable ssdpTimerTask = new Runnable() {
#Override
public void run() {
startStationSearch();
Log.d(TAG,"Running SSDP search - iteration: "+ssdpIteration);
ssdpIteration++;
mHandler.postDelayed(ssdpTimerTask,5000);
}
};