Hi I want to do something like this : I want to send a data to server and wait for receiver byte[] from server . the server will send the array when everything gets. But I want do some timeout becouse sometimes server don't get everything and nothing send.
I do this but it doesn't work. My application always wait for byte[]
public class MyClientTask1 extends AsyncTask<Void, Void, byte[]> {
String dstAddress;
int dstPort;
String response = "";
byte[] data;
int count;
MyClientTask1(String addr, int port) {
dstAddress = addr;
dstPort = port;
}
byte[] buffer = new byte[1024];
#Override
protected byte[] doInBackground(Void... arg0) {
// if (pingHost(1000)) {
socket = null;
try {
socket = new Socket(dstAddress, dstPort);
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
String number = "10";
String sendMessage = number + "\n";
bw.write(sendMessage);
bw.flush();
InputStream stream = socket.getInputStream();
data = new byte[100];
count = stream.read(data);
if(stream.read() == null)
Thread.sleep(2000);
count = stream.read(data);
if( count != 0){
data = null;
}
// while ((count = stream.read(data)) != -1){
// count=stream.read(data);
// }
} catch (UnknownHostException e) {
e.printStackTrace();
isSuccsess = false;
response = "UnknownHostException: " + e.toString();
} catch (IOException e) {
e.printStackTrace();
Log.d("la", "nie udało sie");
isSuccsess = false;
response = "IOException: " + e.toString();
} catch (InterruptedException e) {
e.printStackTrace();
}
return data;
}
#Override
protected void onPostExecute(byte[] bytes) {
super.onPostExecute(bytes);
if(bytes != null) {
if (bytes[0] == (byte) 0xF && bytes[1] == (byte) 0xA && bytes[2] == (byte) 0xA && bytes[3] == (byte) 0xD) {
showToast("zgadza się");
} else {
showToast("nie zgadza się");
}
}
else{
showToast("nie ma nic");
}
pbWheel.setVisibility(View.INVISIBLE);
}
Related
I'm trying to send bytes and receive them over my socket connection but they're not doing either. I'm not sure if its a problem to do with the way i'm sending the bytes and strings or because I don't know how to read from server and client.
Client
public class Client implements Runnable {
private Socket socket;
private ByteArrayOutputStream buffer;
private OutputStream output;
private Stage stage;
public Client() {
try {
this.socket = new Socket("localhost", 1337);
this.socket.setTcpNoDelay(true);
this.socket.setKeepAlive(true);
this.output = this.socket.getOutputStream();
InputStream input = this.socket.getInputStream();
this.buffer = new ByteArrayOutputStream();
Thread connection = new Thread(this);
connection.start();
this.sendPacket(0, ByteBuffer.allocate(16 + "TEST".length()).putInt("TEST".length()).put("TEST".getBytes(Constants.UTF8)).array());
System.out.println("[CLIENT] Successfully connected to server.");
} catch (Exception e) {
IOUtils.output("[CLIENT] Error when connecting to server.");
System.exit(1337);
}
}
#Override
public void run() {
try {
while (this.connected()) {
byte[] bytes = this.buffer.toByteArray();
Constants.received += bytes.length;
if (bytes.length < 8) return;
ByteBuffer cbuf = ByteBuffer.wrap(bytes);
int size = cbuf.getInt();
int id = cbuf.getInt();
if (bytes.length < size + 8) continue;
byte[] data = Arrays.copyOfRange(bytes, 8, 8 + size);
this.processPacket(id, data);
this.buffer.close();
(this.buffer = new ByteArrayOutputStream()).write(bytes, 8 + size, bytes.length - 8 - size);
}
System.out.println("[CLIENT] Disconnected from server.");
System.exit(1337);
} catch (Exception e) {
e.printStackTrace();
}
}
private void processPacket(int id, byte[] bytes) {
ByteBuffer data = ByteBuffer.wrap(bytes);
if (id == 0) {
System.out.println("Received packet from server with id 0");
} else if (id == 1) {
System.out.println("Received packet from server with id 1");
}
}
private void sendPacket(int id, byte[] data) {
try {
ByteBuffer bytebuffer = ByteBuffer.allocate(8 + data.length);
bytebuffer.putInt(data.length);
bytebuffer.putInt(id);
bytebuffer.put(data);
byte[] bytes = bytebuffer.array();
Constants.sent += bytes.length;
this.output.write(bytes);
this.output.flush();
} catch (IOException e) {
try {
socket.close();
} catch (IOException io) {
IOUtils.output("[CLIENT] Error with client.");
System.exit(1337);
}
}
}
private boolean connected() {
return this.socket.isConnected() && !this.socket.isInputShutdown() && !this.socket.isOutputShutdown() && !this.socket.isClosed();
}
}
ServerHandler
public class Handler implements Runnable {
private Socket socket;
private ByteArrayOutputStream buffer;
private OutputStream output;
public Handler(Socket socket) {
this.socket = socket;
try {
this.output = this.socket.getOutputStream();
InputStream input = this.socket.getInputStream();
this.buffer = new ByteArrayOutputStream();
Thread connection = new Thread(this);
connection.start();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void run() {
try {
IOUtils.output("[HANDLER] Connection from " + socket.getInetAddress());
while (connected()) {
byte[] bytes = this.buffer.toByteArray();
if (bytes.length < 8) return;
ByteBuffer buffer = ByteBuffer.wrap(bytes);
int size = buffer.getInt();
int id = buffer.getInt();
if (bytes.length < size + 8) continue;
byte[] data = Arrays.copyOfRange(bytes, 8, 8 + size);
this.processPacket(id, data);
this.buffer.close();
(this.buffer = new ByteArrayOutputStream()).write(bytes, 8 + size, bytes.length - 8 - size);
}
IOUtils.output("[HANDLER] Client ended connection - " + socket.getInetAddress());
} catch (Exception e) {
e.printStackTrace();
}
}
private void sendPacket(int id, byte[] data) {
try {
ByteBuffer bytebuffer = ByteBuffer.allocate(8 + data.length);
bytebuffer.putInt(data.length);
bytebuffer.putInt(id);
bytebuffer.put(data);
byte[] bytes = bytebuffer.array();
this.output.write(bytes);
this.output.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
private void processPacket(int id, byte[] bytes) {
ByteBuffer data = ByteBuffer.wrap(bytes);
if (id == 0) {
IOUtils.output("Recieved packet with id 0");
} else if (id == 1) {
//TODO: authenticate user.
}
}
private boolean connected() {
return this.socket.isConnected() && !this.socket.isInputShutdown() && !this.socket.isOutputShutdown() && !this.socket.isClosed();
}
}
Server
public class Server implements Runnable {
private int port;
private ServerSocket sock;
public Server(int port) {
this.port = port;
launch();
}
private void launch() {
this.run();
}
#Override
public void run() {
try {
sock = new ServerSocket(port);
System.out.println("[SERVER] Server started");
while(!sock.isClosed()) {
new Handler(sock.accept());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
I think this problem might be with ByteArrayOutputStream. I wanted to use ByteBuffer because I heard it was much faster than normal DataInput and output streams.
You are never calling Socket#read inside of your run method... If you dont read anything you dont have anything to work with in your loop, even when you are connected!
Take a look at this Tutorial about Sockets:
https://docs.oracle.com/javase/tutorial/networking/sockets/readingWriting.html
Your server code should use ServerSocket instead of Socket. Socket is used to represent Client Socket objects in Java.
The task is to broadcast sound through a socket in one thread and in the other to send a string through the same socket. The result should be read on the client side. All this I do through DataInputStream and DataOutputStream and an array of bytes.
Receiving and transmitting data is normal, if the data is transmitted through a single thread. But if you send a text string during the transmission of the sound streaming, it creates the feeling that the data is mixed in a heap, because the sound rips, and the lines too are not possible to get.
Are there any guesses why this can happen?
This is the little samples of my code:
(Text sending)
public void sendMessage(byte[] msg, int key) {
OutputStream mOutputStream;
try {
Socket socket = getSocket();
if (socket == null) {
Log.d(CLIENT_TAG, "Socket is null, wtf?");
} else if (socket.getOutputStream() == null) {
Log.d(CLIENT_TAG, "Socket output stream is null, wtf?");
}
mOutputStream = getSocket().getOutputStream();
DataOutputStream dos = new DataOutputStream(mOutputStream);
dos.writeUTF("####");
dos.writeInt(key);
dos.writeInt(msg.length);
dos.flush();
dos.write(msg);
dos.flush();
logD("MESSAGE " + msg.length);
} catch (UnknownHostException e) {
Log.d(CLIENT_TAG, "Unknown Host", e);
} catch (IOException e) {
Log.d(CLIENT_TAG, "I/O Exception", e);
} catch (Exception e) {
Log.d(CLIENT_TAG, "Error3", e);
}
Log.d(CLIENT_TAG, "Client sent message: " + msg);
}
(Audio sending)
#Override
public void run() {
audioRecord.startRecording();
byte[] buffer = new byte[recBufSize];
DataOutputStream dataOutputStream = new DataOutputStream(mOutputStream);
if (mOutputStream != null) {
try {
dataOutputStream.writeInt(SOUND_KEY);
dataOutputStream.writeInt(recBufSize);
logD("AUDIO OUT " + buffer.length);
while (isRecording) {
int readSize = audioRecord.read(buffer, 0, recBufSize);
dataOutputStream.writeUTF("####");
dataOutputStream.writeInt(readSize);
dataOutputStream.write(buffer, 0, readSize);
dataOutputStream.flush();
double sum = 0;
for (int i = 0; i < readSize; i++) {
sum += buffer[i] * buffer[i];
}
if (readSize > 0) {
final double amplitude = sum / readSize;
int result = (int) avgQueue(Math.sqrt(amplitude), 10);
if (mSoundControl != null)
mSoundControl.setSoundLevel(result);
logD("AMPLITUDE " + result);
}
}
} catch (Exception e) {
logD(e.getMessage());
}
audioRecord.stop();
}
(Data receiving)
DataInputStream is = new DataInputStream(inStream);
while (!Thread.currentThread().isInterrupted()) {
try {
if (is.readUTF().equals("####")) {
token = is.readInt();
dataKey = token;
switch (token) {
case 0:
break;
case CONTROL_KEY:
readControlMessage(is);
break;
case IMAGE_KEY:
readImageMessage(is);
break;
case SOUND_KEY:
readSoundMessage(is);
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
Please, tell me what is wrong
I'm creating my own server-software from scratch using this library.
Right now the client sends the server a Handshake packet, the server decodes it using a Handshake Codec and returns with a Response message encoded with a Response Codec, however I never get a Ping packet.
Here is my code for encoding the Response message to the server.
public class ResponseCodec implements Codec<ResponseMessage> {
#Override
public ResponseMessage decode(DataInputStream dataInputStream) {
String json = ByteUtilities.readUTF8(dataInputStream);
return new ResponseMessage(json);
}
#Override
public DataOutputStream encode(DataOutputStream dataOutputStream, ResponseMessage responseMessage) {
ByteArrayOutputStream packetArray = new ByteArrayOutputStream();
DataOutputStream packetStream = new DataOutputStream(packetArray);
ByteUtilities.writeVarInt(packetStream, 0x00);
ByteUtilities.writeUTF8(packetStream, responseMessage.getJson());
ByteUtilities.writeVarInt(dataOutputStream, packetArray.toByteArray().length);
try {
dataOutputStream.write(packetArray.toByteArray());
} catch (Exception e) {
e.printStackTrace();
}
return dataOutputStream;
}
}
And here is my connection listener:
server.setConnectionListener(new ConnectionListener() {
#Override
public void onConnect(Socket socket, DataInputStream dataInputStream) throws Exception {
//header
int packetSize = ByteUtilities.readVarInt(dataInputStream);
int packetId = ByteUtilities.readVarInt(dataInputStream);
// writing handlers
OutputStream outputStream = socket.getOutputStream();
DataOutputStream socketStream = new DataOutputStream(outputStream);
//identification
if(packetId == 0x00) {
// decode
HandshakeCodec codec = new HandshakeCodec();
HandshakeMessage message = codec.decode(dataInputStream);
if(!(message.getProtocolVersion() == 47)) {
System.out.println("Client " + message.getAddress() + ":" + message.getPort() + " seems to have a incompatible client.");
}
ResponseCodec responseCodec = new ResponseCodec();
StringBuilder text = new StringBuilder();
BufferedReader formatReader = new BufferedReader(new InputStreamReader(getClass().getClassLoader().getResourceAsStream("ResponseFormat.txt")));
String line = formatReader.readLine();
while (line != null) {
text.append(line);
text.append(System.lineSeparator());
line = formatReader.readLine();
}
String everything = text.toString();
String accountedWithVariables = everything
.replaceAll("MAX_PLAYERS", "" + maxPlayers)
.replaceAll("ONLINE_PLAYERS", "" + BasicServer.onlinePlayers)
.replaceAll("MOTD", motd);
ResponseMessage responseMessage = new ResponseMessage(accountedWithVariables);
responseCodec.encode(socketStream, responseMessage);
}
if(packetId == 0x01) {
long pingLong = dataInputStream.readLong();
PongCodec codec = new PongCodec();
PongMessage message = new PongMessage(pingLong);
codec.encode(socketStream, message);
}
}
#Override
public void onCaughtException(Exception e) {
System.out.println("Main thread has recieved a exception: " + e.getMessage());
e.printStackTrace();
}
});
I want sends and receive an object and file the order is
client -> server by ObjectOut(In)putStream
client -> server String(file name) by DataIn(Out)putStrean writeUTF
client -> server by BufferedIn(Out)putStream
server -> client by ObjectOut(In)putStream
but when the code reaches on 3 writing file takes forever (I think...it is waiting) the critical code is
byte[] data = new byte[BUFFER_SIZE];
while ((length = bis.read(data)) != -1) {
bos.write(data, 0, length);
System.out.println(length);
}
bis(BufferedInputStream).read() do not proceed when I print the length the output is
4096
4096
879
then just wait...
is there anyone who knows what is the problem or solution?
Server thread
public void run() {
System.out.println("\n New FileUploadServer thread started");
msg = (Message) objComm.recvObject(clientSocket);
System.out.println("server get message");
if (checkState(msg.getState()))
System.out.println(clientAddr + " session over");
System.out.println("");
}
private boolean checkState(int _state) {
switch (_state) {
case ST_EXCEL_FILE:
return receiveExcel();
default:
return false;
}
}
private boolean receiveExcel() {
Message sendMsg = receiveStr();
System.out.println("receiveStr() success");
BufferedInputStream bis;
DataOutputStream dos;
DataInputStream dis;
FileOutputStream fos;
BufferedOutputStream bos;
VoteInfo sendVoteInfo = (VoteInfo) msg.getObj();
try {
dis = new DataInputStream(clientSocket.getInputStream());
dos = new DataOutputStream(clientSocket.getOutputStream());
// check file name extension is "xls" or "xlsx"
String fName = dis.readUTF();
int idx = fName.lastIndexOf(".");
String extension = fName.substring(idx + 1, fName.length());
if (!excelFileCheck(extension))
return false;
dos.writeUTF("read_ok");
dos.flush();
System.out.println("File name: " + fName);
File f = new File(EXCEL_FILE_DIR + fName);
fos = new FileOutputStream(f);
bos = new BufferedOutputStream(fos);
bis = new BufferedInputStream(clientSocket.getInputStream());
int length;
byte[] data = new byte[BUFFER_SIZE];
while ((length = bis.read(data)) != -1) {
bos.write(data, 0, length);
System.out.println(length);
}
bos.flush();
// send success message to web server
System.out.println("kangji2");
objComm.sendObject(sendMsg, clientSocket);
System.out.println("File receive success!");
if (!dataToDB.excelToDB(EXCEL_FILE_DIR + fName, extension)) {
//delete all db related to this excel file here
return false;
} else {
}
bos.close();
fos.close();
dis.close();
clientSocket.close();
// send candidates information to DB server
return makeResult(sendVoteInfo);
} catch (IOException e) {
System.out.println("ReceiveExcel error");
e.printStackTrace();
}
return false;
}
public class ObjectComm {
private Message receiveMsg = null;
private ObjectOutputStream out = null;
private ObjectInputStream in = null;
public Message commObject(Message _sendMsg, Socket _clntSocket) {
if (!_clntSocket.isConnected()) {
System.out.println("clnt Socket not connected");
return null;
}
try {
out = new ObjectOutputStream(_clntSocket.getOutputStream());
out.writeObject(_sendMsg);
out.flush();
System.out.println("kangji1");
in = new ObjectInputStream(_clntSocket.getInputStream());
receiveMsg = (Message) in.readObject();
System.out.println("kangji2");
return receiveMsg;
} catch (Exception e) {
System.out.println("commObject err");
e.printStackTrace();
return null;
}
}
public boolean sendObject(Message _msg, Socket _clntSocket) {
if (!_clntSocket.isConnected()) {
System.out.println("clnt Socket not connected");
return false;
}
try {
out = new ObjectOutputStream(_clntSocket.getOutputStream());
out.writeObject(_msg);
out.flush();
return true;
} catch (IOException e) {
System.out.println("Object comm send err");
e.printStackTrace();
return false;
}
}
public Message recvObject(Socket _clntSocket) {
if (!_clntSocket.isConnected()) {
System.out.println("clnt Socket not connected");
return null;
}
try {
in = new ObjectInputStream(_clntSocket.getInputStream());
receiveMsg = (Message) in.readObject();
return receiveMsg;
} catch (Exception e) {
System.out.println("Object comm recvObject err");
e.printStackTrace();
return null;
}
}
}
Did you close the connection in client side (sender side, or wherever opposite of your input stream) ? read(byte[], int, int ) in BufferedInputStream will return when end of the stream has been reached.
http://docs.oracle.com/javase/7/docs/api/java/io/BufferedInputStream.html#read(byte[],%20int,%20int)
client -> server by ObjectOut(In)putStream
client -> server String(file name) by DataIn(Out)putStrean writeUTF
client -> server by BufferedIn(Out)putStream
server -> client by ObjectOut(In)putStream
Too much stuff here.
Playing with streams at different levels of your stream stack simply does not work.
If you want to send objects, use the ObjectInput/OutputStreams for everything. Construct them as follows:
new ObjectOutputStream(new BufferedOutputStream(...))
and
new ObjectInputStream(new BufferedInputStream(...))
Send the objects with writeObject(); send the strings with writeObject() or writeUTF(); send byte arrays via ObjectOutputStream.write(); and use the complementary methods of ObjectInputStream at the other end.
I've got the following code for my server:
try
{
Socket = serverSocket.accept();
inputStreamReader = new InputStreamReader(Socket.getInputStream());
bufferedReader = new BufferedReader(inputStreamReader);
message = bufferedReader.readLine();
switch(message)
{
case "GET / HTTP/1.1":
{
break;
}
default:
{
System.out.println(message);
}
}
inputStreamReader.close();
Socket.close();
}
catch(Exception e)
{
System.out.println("Problem while waiting for messages (" + e.toString() + ")");
}
and this code for my (Android) Client:
private String GetPC(String strToPC)
{
final String strToPCFinal = strToPC;
Thread SendingThread = new Thread()
{
public void run()
{
try
{
client = new Socket("192.168.178.22", 14510);
printwriter = new PrintWriter(client.getOutputStream());
printwriter.write(strToPCFinal);
printwriter.flush();
printwriter.close();
client.close();
}
catch(Exception e)
{
System.out.println("Problem while sending test message (" + e.toString() + ")");
}
}
};
SendingThread.start();
return "";
}
My question now is: How can I get an answer (if the text is successfully transmitted to my PC) back to my Android client?
private String readReply(SocketChannel socket) throws IOException {
final StringBuilder reply = new StringBuilder();
final ByteBuffer buffer = ByteBuffer.allocate(512);
int numBytesRead;
do {
numBytesRead = socket.read(buffer);
if (numBytesRead > 0) {
buffer.flip();
reply.append(decoder.decode(buffer).toString());
buffer.clear();
if (reply.indexOf(".") > -1) {
break;
}
}
} while (numBytesRead > -1);
socket.close();
return reply.toString();
}
Use the snippet below to send to server (if localhost)
private String send(String command) throws IOException {
final SocketAddress address = new InetSocketAddress("10.0.2.2", PORT);
final SocketChannel socket = SocketChannel.open(address);
final CharBuffer buffer = CharBuffer.wrap(command);
socket.write(encoder.encode(buffer));
final String reply = readReply(socket); // Get response
socket.close();
return reply;
}