Am getting set socket option failed exception in Android. What am I doing wrong ?
setsockopt failed: EBADF (Bad file number)
For the following code:
int timeout = 500;
Socket socket = new Socket(InetAddress.getByAddress(new byte[]{10, 0, 2, 2}),
Integer.parseInt(m.destPort));
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject(m);
oos.close();
socket.setSoTimeout(timeOut);
ObjectInputStream iis = new ObjectInputStream(socket.getInputStream());
iis.readObject();
iis.close();
socket.close();
Closing the input or output stream of a socket closes the other stream and the socket.
Change
oos.close();
to
oos.flush();
(Poor coding in Android. It should throw a SocketException: socket closed.)
Related
I am unable to send data from the server(python) to the client (android java). Java client socket gets shutdown before it accepts data from the server.
no Error on the Python side it sends data as well but the java client socket is closed and doesn't accept data
Error W/System.err: java.net.SocketException: Socket is closed
at java.net.Socket.getInputStream(Socket.java:923) W/System.err: at
com.example.smd.TcpDataHandler.doInBackground(TcpDataHandler.java:66)
at com.example.smd.TcpDataHandler.doInBackground(TcpDataHandler.java:20)
python code
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind(('ip' , port))
server_socket.listen(10)
print("server is listening")
(client_socket,client_adress) = server_socket.accept()
print("Socket completed")
#client_socket.shutdown(socket.SHUT_WR)
#while True:
print('waitingg.....................')
try:
data2=b''
while True:
buf = client_socket.recv(65535)
data2 += buf
if not buf:
break
client_input = data2
print("data recieve ")
b=base64.b64decode(client_input)
#print(b)
imageStream = io.BytesIO(client_input)
imageFile = Image.open(imageStream)
# i = Image.fromarray(imageFile, mode='L').convert('1')
imageFile.LOAD_TUNCATED_IMAGES=True
print(imageFile.size)
#this is the image ,here you cna verify via image size
modelRes=test(imageFile)
modelRes=modelRes[0]
modelRes= int(modelRes[0])
data = database(decode(imageFile))
print(data)
#json_obj = [{ "model_res": modelRes , "decode_data": data}]
x = { "model_res": modelRes, "decode_res": data}
# convert into JSON:
data = json.dumps(x)
print('data is : '+data)
client_socket.send(data.encode())
print('data sended')
client_socket.shutdown(socket.SHUT_WR)
print('Reciving BYE message')
data3 = client_socket.recv(1024).decode()
print('Program ended : '+data3)
client_socket.close()
server_socket.close()
except Exception as e:
print(e)
JAVA codee
socket=new Socket("ip", port);
System.out.println("Socket donee : ");
byte[] bArray = new byte[(int) file.length()];
try{
fis = new FileInputStream(file);
fis.read(bArray);
fis.close();
}catch(IOException ioExp){
ioExp.printStackTrace();
}
Log.d("Data to bytes"," images has been converted to byte");
out = new DataOutputStream(socket.getOutputStream());
out.write(bArray);
out.flush();
out.close();
Log.d("Data send"," Data has been send Successfully");
Log.d("waiting responce"," Waiting ford data from Python");
InputStreamReader streamReader= new
InputStreamReader(socket.getInputStream());
BufferedReader reader= new BufferedReader(streamReader);
String value= reader.readLine();
System.out.println(value);
Log.d("Data Revieve"," Recieve data Successfully");
reader.close();
dataRec="";
dataRec=value;
OutputStream outputStream = socket.getOutputStream();
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
System.out.println("Sending BYE MSG");
// write the message we want to send
dataOutputStream.writeUTF("Byeee serverrrrrr");
dataOutputStream.flush(); // send the message
dataOutputStream.close(); // close the output stream when we're done.
socket.close();
Log.d("Socket closed "," Socket has been Successfully");
In your java code you have the lines
out = new DataOutputStream(socket.getOutputStream());
out.write(bArray);
out.flush();
out.close();
That last line out.close(); also closes the socket. This may not be obvious. DataOutputStream extends FilterOutputStream and inherits its close method. FilterOutputStream.close() also closes the wrapped OutputStream which in this case is socket.getOutputStream(). The Javadocs for socket.getOutputStream() state
Closing the returned OutputStream will close the associated socket.
Since your python code reads until end-of-stream/end-of-file, you need some way for Java signal to signal to its python peer that it is finished writing data. Java provides this through the socket.shutdownOutput() method. Thus, if you replace out.close(); with socket.shutdownOutput() you should get the effect you need:
out = new DataOutputStream(socket.getOutputStream());
out.write(bArray);
out.flush();
socket.shutdownOutput();
im trying to implement a basic chat applcation via sockets but i have problem with ObjectInputStream. Im using both write-read methods in while(true) loop and compiling process got stuck when there is nothing to read and waits for it infinitly. Thus, i need to check wheter is it empty or not before read it.
Here is my codes.
Server:
Socket socket = server.accept();
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject("Server connected!");
oos.flush();
String message = (String) ois.readObject();
System.out.println(ois.available());
txtChat.setText(message);
while(true) {
if(sendMessage) {
oos.writeObject(txtMessage.getText());
oos.flush();
sendMessage = false;
}
while(!sendMessage) {
message = (String) ois.readObject();
txtChat.setText(txtChat.getText()+"\n"+"Client: "+message);
}
Thread.sleep(100);
}
Client:
socket = new Socket(host.getHostName(), 9876);
oos = new ObjectOutputStream(socket.getOutputStream());
ois = new ObjectInputStream(socket.getInputStream());
oos.flush();
String message = (String) ois.readObject();
txtChat.setText(message);
while(true) {
message = (String) ois.readObject();
txtChat.setText(txtChat.getText()+"\n"+"Server: "+message);
if(sendMessage) {
oos.writeObject(txtMessage.getText());
oos.flush();
sendMessage = false;
}
Thread.sleep(100);
}
The stream is either closed or open.
The input stream isn't aware that it is closed until you read something out of it. This is precisely why there exists no such isClosed() method on the stream.
You can read the bytes from the stream, into an object. At best you'll be able to construct the object. Else, you should handle the IO exception and decide accordingly.
Optionally, you can check how many bytes you can read without blocking. If it's 0, you're looking at an empty stream that is waiting for input.
inputStream.available() != 0 //handle exception
I set up a client and server sockets. When I use classes ObjectOutputStream and ObjectInputStream and the method readObject/writeObject everything works fine.
It simulates communication with a robot that I know for sure interprets correctly only method
DataOutputStream.writeBytes.
So I set up the new architecture for simulation since the robot is not available for testing on a daily basis.
In the following code where ObjectOutputStream/ObjectInputStream readObject/writeObject were replaced with DataInputStream/DataOutputStream writeBytes and IOutils.toByteArray.
The server socket correctly receives the message but when it tries to write back a response I get a broken pipe as if the connection was closed somewhere.
Notice that I never close sockets or streams because the robot can answer even after 30 seconds.
Any help to make DataOutputStream.writeBytes work would be appreciated.
Here's the non-working code:
Client:
Socket serverSocket = new Socket("server", 9899);
DataOutputStream outputStream = new DataOutputStream(serverSocket.getOutputStream());
//ObjectOutputStream outputStream = new ObjectOutputStream(serverSocket.getOutputStream());
//outputStream.writeObject("\n" + "message" + "\r");
outputStream.writeBytes("\n" + "message" + "\r");
outputStream.flush();
DataInputStream inputStream = new DataInputStream(serverSocket.getInputStream());
//ObjectInputStream inputStream = new ObjectInputStream(serverSocket.getInputStream());
byte [] bytes = IOUtils.toByteArray(inputStream);
String serverResponse = new String(bytes,"UTF-8");
// String serverResponse = (String)inputStream.readObject();
Server:
ServerSocket serverSocket = new ServerSocket(9899);
while (true) {
Socket socket = serverSocket.accept();
//ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream());
DataInputStream inputStream = new DataInputStream(socket.getInputStream());
byte [] bytes = IOUtils.toByteArray(inputStream);
String message = new String(bytes,"UTF-8");
//String message = (String) inputStream.readObject();
Thread.sleep(15000);
//ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());
DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream());
//outputStream.writeObject("server response");
outputStream.writeBytes("server response"); //EXCEPTION THROWN HERE FOR BROKEN PIPE
outputStream.flush();
}
Thanks for your time
IOUtils.toString(InputStream) must read the stream until its end, which would imply that the peer has disconnected. So you can't write to it.
If you're exchanging Strings with data streams you should use writeUTF() and readUTF().
Or read and write lines, with a BufferedReader/Writer.
I'm trying to work on multiple AVD in Android and sending data between them using Sockets.
Serverside code-snippet:
ServerSocket ss = new ServerSocket(10000);
Log.v("ReceiverTask", "Receiver waiting for requests");
connectedSocket = ss.accept();
ObjectInputStream ois = new ObjectInputStream(connectedSocket.getInputStream());
Object obj = ois.readObject();
ois.close();
ss.close();
Client side code:
Socket socket = new Socket(InetAddress.getByAddress(new byte[]{10, 0, 2, 2}),njr.sendTo());
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(njr);
Log.d("Client","Object send successfull");
oos.flush();
bos.flush();
oos.reset();
oos.close();
bos.close();
socket.close();
The problem is that The objects that are sent from one AVD (as given by log) is not being received at other AVD. This happens sometimes and not always at a same point. Any hints as to what could be the problem???
use oos.flush() at the end in client.
socket = new Socket(InetAddress.getByAddress(new byte[]{10, 0, 2, 2}),njr.sendTo());
bos = new BufferedOutputStream(socket.getOutputStream());
oos = new ObjectOutputStream(bos);
oos.writeObject(njr);
oos.flush();
oos.close();
Log.d("Client","Object send successfull");
Close the stream after reading, else it will assume that its still open
oos.Close();
For some reasons i have to set up on android SocketServer which waits for connection with computer. All is going good, socket with client (computer) is creating, but streams don't open. It's just pausing without any error or message.
client:
s = new Socket(ip, 4567);
ois = new ObjectInputStream(s.getInputStream());
System.out.println("ois..");// not showing, so can't open input stream
oos = new ObjectOutputStream(s.getOutputStream());
System.out.println("oos.."); // same here
server:
socket = new ServerSocket(4567);
System.out.println("Waiting for connection,,"); // showing
client = socket.accept();
System.out.println("Connected"); //showing
ois = new ObjectInputStream(client.getInputStream());
System.out.println("ois.."); // not showing
oos = new ObjectOutputStream(client.getOutputStream());
System.out.println("oos.."); // not showing too
System.out.println("Stream,s opened");
My apk has INTERNET premissions. I'm using 4567 port. Any other application doesn't block the port.
What can be wrong?
Try opening the ObjectOutputStream first in your server.
socket = new ServerSocket(4567);
System.out.println("Waiting for connection,,"); // showing
client = socket.accept();
System.out.println("Connected"); //showing
oos = new ObjectOutputStream(client.getOutputStream());
ois = new ObjectInputStream(client.getInputStream());
System.out.println("Stream,s opened");
I don't see any timeouts in there, which is why it just stops.
There's probably some network problem; have you verified the IP address of the device is correct?
It's unlikely, but there could be some firewall rule blocking the connection.