TCP Time out while fetching MetaData for Radio Streaming in Blackberry - java

I am creating an Radio app which will stream from the various different URL's.
Now while fetching the stream from the url's we also want the content that is which song is playing on i.e metadata.
Now for this i run another thread in a TimerTask that will create the HTTP connection say like after every 40 seconds.
While using the simulator for OS 5 and above there is no problem but when i run the same thread for two to three iterations the metadata is recieved consistently but afterwards we got the TCP time out exception and this halts the over all system and device even losts the internet connection.
Can you please suggets any alternatives which can solve the problem.
I am also sharing the code that will get the metaData from the streaming URL.
class metaData extends Thread {
public void run() {
try {
boolean metaDataCheckBit = false;
StreamConnection streamConnection = (StreamConnection)Connector.open(url);
HttpConnection httpConnection = (HttpConnection)streamConnection;
httpConnection.setRequestProperty("Icy-metadata", "1");
int httpStatus = httpConnection.getResponseCode();
if (httpStatus==HttpConnection.HTTP_OK) {
String mint = httpConnection.getHeaderField("icy-metaint");
InputStream inputStream = streamConnection.openInputStream();
int length = Integer.parseInt(mint);
int b = 0;
int count = 0;
while(count++ < length){
b = inputStream.read();
}
int metalength = ((int)b)*16;
if (metalength <= 0) return;
byte buf[] = new byte[metalength];
inputStream.read(buf,0,buf.length);
final String metaData = new String(buf);
final String streamTille =
metaData.substring(14, metaData.indexOf("StreamUrl")-2);
System.out.println("Stream Title--------"+streamTille);
UiApplication.getUiApplication().invokeAndWait(new Runnable(){
public void run() {
try {
titleRf.setText(streamTille);
} catch (Exception e) {
System.out.println("Exception: " + e.toString());
}
}
});
}
} catch (Exception e){
System.out.println("Exception in meta data...."+e);
}
}
}

Related

Java TCP-Server socket connection keepalive

I want to communicate as a TCP Server on Port 2000 and 2001 with my TCP Client (Machine which sends Bytestreams).
Therefore I programmed a Spring Boot Application in Java.
This Question is only for Port 2001:
I use Camunda as BPMN-Engine for executing and orchestrating.
I start Threads like this:
package com.example.workflow;
import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.JavaDelegate;
public class StartTCPServersDelegate implements JavaDelegate {
#Override
public void execute(DelegateExecution delegateExecution) throws Exception {
Runnable serverZyklisch = new ServerZyklisch();
Runnable serverAzyklisch = new ServerAzyklisch((String) delegateExecution.getVariable("param"));
Thread t1 = new Thread(serverZyklisch);
t1.start();
System.out.println("Thread Zyklisch gestartet");
Thread t2 = new Thread(serverAzyklisch);
t2.start();
System.out.println("Thread Azyk. gestartet");
String val1 = (String) delegateExecution.getVariable("param");
int valueParam = Integer.parseInt(val1);
System.out.println("Param ist: "+valueParam);
}
}
This is my ServerAzyklisch Class:
public class ServerAzyklisch implements Runnable, JavaDelegate {
private ServerSocket ssocket;
String param;
HexToByteConverter hexToByteConverter = new HexToByteConverter();
public ServerAzyklisch(String Pparam) throws IOException {
ssocket = new ServerSocket(2000);
param = Pparam;
}
public void run() {
System.out.println(param+"Paraaam");
InputStream in;
OutputStream out = null;
Socket socket;
while(true){
try {
socket = ssocket.accept();
in = socket.getInputStream();
out = socket.getOutputStream();
byte []data = new byte[132];
int numBytes = 0;
byte[]durch = hexToByteConverter.hexStringToByteArray("333333330041006400040000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
byte[]durchlauf = hexToByteConverter.hexStringToByteArray("333333330041006400040000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
byte[]Pressen1hexdump111 = hexToByteConverter.hexStringToByteArray("33333333003d0064000600000004004001c9c78900010000006f00000000000000000000000000010000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005");
byte[]Pressen1hexdump110 = hexToByteConverter.hexStringToByteArray("33333333003d0064000600000004004001c9c78900010000006e0000000000000000000000000001000000000014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"+param);
byte[]Pressen2hexdump = hexToByteConverter.hexStringToByteArray("3333333300400065000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
byte[]Pressen3hexdump = hexToByteConverter.hexStringToByteArray("3333333300400065001400000000003d01c9c7890001000000c9000000000000000000000000000100000000001e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
byte[]Pressen3hexdumpNextBohrer = hexToByteConverter.hexStringToByteArray("3333333300400065001400000000003f01c9c789000100000078000000000000000000000000000100000000001e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002");
byte[]Pressen4hexdumpNextRSCIDBohrer = hexToByteConverter.hexStringToByteArray("33333333003f0065001400000000003d01c9c78900010000007a000000000000000000000000000100000000001e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
//gleichen Stream zurückschicken, der angekommen ist, für Durchlauf
while((numBytes = in.read(data)) != -1){
System.out.println(Arrays.toString(data));
out.write(Pressen1hexdump110);
out.write(Pressen2hexdump);
out.write(Pressen3hexdumpNextBohrer);
//out.write(durchlauf);
}
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
#Override
public void execute(DelegateExecution delegateExecution) throws IOException {
}
}
I get everytime a different Result to my Client, so the behaviour is always another. But I want to send once all three bytearrays to my Client. I think something is wrong with my while loop.
Do you have any idea ?
By the comments, the communication is based on request-response pairs. You need to read 3 messages from the client, and return a response for each message. To do this, replace the while loop with:
readMessage(in, data);
out.write(Pressen1hexdump110);
readMessage(in, data);
out.write(Pressen2hexdump);
readMessage(in, data);
out.write(Pressen3hexdumpNextBohrer);
where the readMessage method is a new method you must add, that reads a complete request from the client.
If the client requests are always 128 bytes, there is a convenient method in DataInputStream that you can use:
void readMessage(InputStream in, byte[] buffer) throws IOException {
new DataInputStream(in).readFully(buffer, 0, 128);
}
In the general case the readMessage method would have to look something like this in pseudo-code:
void readMessage(InputStream in, byte[] buffer) {
// Read a message
while message is not complete:
read from "in" into "buffer"
if "in" was closed: throw an exception because the connection was closed mid-request
else: incorporate newly read data from "buffer" in message
done
}

Single URLConnection to fetch only the first line in java using BufferedReader

I am trying to write a Java program that should automatically download text from a website if and only if it gets updated. The problem I am running into is using only one HTTPURLConnection to do that because if i don't there will be billions of HTTPURLConnections to the web server since I am using a while(true) loop. Here is my work-in-progress, the getMsg() method receives a url and opens an HTTPURLConnection. Currently I am starting a new connection every time I have to read a line, which is not the most efficient way I am sure. How do I keep reading the same line with the same HTTPURLConnection?
// Starts a new URLConnection to "localhost/currentmsg.dat"
// Receives JSON string from the URLConnection
// Sets up a different variable for each object received from the URL for eg. if delete=1 means that the admin is requesting to delete a message from the screen.
import java.io.*;
import java.net.*;
import org.json.*;
import java.io.*;
import java.util.Scanner;
public class jListenerURL {
// Current arguments retrieved from the URL
private static int msgID = 0;
private static int aptID = 1; // Apartment ID of current device
private static int unitID = 3; // Unit ID of current device
static String message; // Message received from admin
static int delete; // Delete a message?
static int dmsgID; // What message to delete?
public static void jListener() {
URL url;
boolean keepGoing = true;
String msg = "";
try {
url = new URL("http://www.lotussmoke.com/msgtest/currentmsg.dat");
while (keepGoing) {
msg = getMsg(url);
JSONObject jObj = null;
try {
jObj = new JSONObject(msg);
}
catch (JSONException je) {
System.out.println("JSON Exception for message, try restarting terminal.");
}
int current = jObj.getInt("msgID");
int targetaptID = jObj.getInt("aptID");
int targetunitID = jObj.getInt("unitID");
// Keep listening, if the message changes meaning a different msgID then print that message
if (current!=msgID && targetaptID == aptID && targetunitID == unitID) {
msgID = jObj.getInt("msgID");
message = jObj.getString("message");
delete = jObj.getInt("delete");
dmsgID = jObj.getInt("dmsgID");
if (delete==1) {
// Delete a message
System.out.println("Delete msg ID? " + dmsgID);
continue;
}
System.out.println("Message ID: " + msgID);
System.out.println("Apartment ID: " + aptID);
System.out.println("Unit ID: " + unitID);
System.out.println("Message: " + message);
}
}
}
catch (MalformedURLException e) {
System.err.println();
}
}
public static void main(String args[]) throws Exception {
jListener();
}
private static String getMsg(URL url) {
HttpURLConnection con = null;
try {
con = (HttpURLConnection) url.openConnection();
} catch (IOException e1) {
e1.printStackTrace();
}
BufferedReader in = null;
String msg = "";
try {
in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String received;
while((received = in.readLine()) != null) {
//System.out.println(received);
msg = received;
}
in.close();
}
catch (IOException e) {
e.printStackTrace();
}
return msg;
}
}
Why don't you simply declare your HttpURLConnection object outside of your while loop ? It will then not open a connection at each call inside the loop.
HttpURLConnection cannot be reused, but it can reuse an open connection to the same server internally by setting the header Connection: keep-alive. It doesn't make sense if you connect to different servers, obviously.
One way to efficiently test whether there are changes, is to use If-Modified-Since header or the like If-Unmodified-Since, If-None-Match or If-Match (see HTTP Headers). In this case the web-server decides to deliver a new document if there are changes or just sends the response code 304 Not Modified without a body.
One last thing regarding the use of members (and especially static members): I'd refactor this code and the only item which would be left as static is static void main(). You can see the static members as some kind of global variables. Observing something like 'the connection is returning the same message' might be a effect of inappropriate exception handling and usage of static members.

Java the best way of waiting & getting data from your client

I started learning networking with the main networking package in JDK, it's pretty simple and easy after a few examples. But now I am interested into making multi-client applications like a chat system.
My structure idea so far is like this:
Connection handler class, which handles incoming connections, and holds the list of clients.
If new connection was found, create a new client object, start it's thread (Client object will implement runnable, so it will start it's own looping service, it will loop for new packets received), and add it to the list.
I create a new thread for each client instead of looping through all clients because the reading from client process stops the whole execution and will wait for the client to send data, which is kinda annoys me and this is my issue there.
I have created a simple console app that receives messages from the client, but now I want to detect disconnections. I read that bufferedReader .read() method returns -1 if user is not connected, so I thought I could loop and do that every number of seconds to every client, but the thing is, the client must send a packet in order to .read() it, so let's say if you do .read() it will wait & stop the whole thread until packet is received, (I think).
This is my current code which gets messages from client:
public boolean isConnected() {
try {
this.in.read();
this.lastCheck = System.currentTimeMillis();
return true;
} catch (IOException e) {
if (!inConnection()) {
System.out.println("User disconnected");
try {
this.destruct();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
return false;
}
private boolean inConnection() {
return System.currentTimeMillis() - lastCheck < this.maxTime;
}
public void startClientService() throws IOException {
while(!this.session.isClosed()) {
if (System.currentTimeMillis() - this.checkTime > 600) {
System.out.println(System.currentTimeMillis() - this.checkTime);
if (this.isConnected()) {
int packetType = this.dataIn.readInt();
packets.getPacket(packetType);
}
}
}
}
public void destruct() throws IOException {
this.session.close();
this.connection.removeClient(this);
System.out.println("Session killed");
}
Basically what happens here, I am sending a integer packed from the client, I might have many things to do so therefore I can set many unique packet ID's, so if I want to receive and process a chat message, the packet id is 216, the client sends a int 216, server reads the packet, enters the switch loop of all packet ids and detects if its really 216, if yes it gets the instance of the packed class that handles messages & gets the bytes of the received message like this:
public class Chat implements Packet {
#Override
public void processPacket(Session c) {
String message = readMessage(c);
System.out.println("Message: " + message);
}
private String readMessage(Session c) {
byte[] data = c.readBytes();
String message = null;
try {
message = new String(data, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return message;
}
}
And this is how I read bytes:
public byte[] readBytes() {
int len;
byte[] data = null;
try {
len = this.dataIn.readInt();
data = new byte[len];
if (len > 0) {
this.dataIn.readFully(data);
}
} catch (IOException e) {
e.printStackTrace();
}
return data;
}
Okay my problem:
after adding the is disconnected detection, when I send my message, nothing happens. This is probably due to the .read() it stops and is waiting for a response. BUT if I write a message again, I will get the message in server.
This is my temporary, ugly client:
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
Socket socket = new Socket("127.0.0.1", 43594);
Scanner r = new Scanner(System.in);
PrintWriter out = new PrintWriter(socket.getOutputStream());
String input;
while(true) {
input = r.next();
if (input != null) {
sendMessage(input, out);
}
}
}
public static void sendMessage(String message, PrintWriter out) {
byte[] encoded = encode(message);
out.write(0);
out.println(encoded + "\n");
out.flush();
}
public static byte[] encode(String s) {
return DatatypeConverter.parseBase64Binary(s);
}
public static String decode(byte[] s) {
return DatatypeConverter.printBase64Binary(s);
}
}
My question is: What is a better way of reading data from client without making the application wait for it and actually loop everytime? OR maybe should I have a new thread for checking if user is online so it's 2 threads per 1 client?
If someone needs my session object (client object):
public class Session extends Thread implements Runnable {
private Socket session;
private Client client;
private PrintWriter out;
private BufferedReader in;
private PacketHandler packets;
private DataInputStream dataIn;
private ConnectionHandler connection;
private final int checkTime = 1600;
private final int maxTime = 22000;
private long lastCheck;
public Session(Socket session) {
this.session = session;
this.client = new Client(this);
try {
this.setStream();
} catch (IOException e) {
e.printStackTrace();
}
this.packets = new PacketHandler(this);
System.out.println("[New session created]: " + session.getRemoteSocketAddress());
}
public void setConnectionHandler(ConnectionHandler c) {
this.connection = c;
}
public void run() {
try {
this.startClientService();
} catch (IOException e) {
e.printStackTrace();
}
}
public void setStream() throws IOException {
this.out = new PrintWriter(this.session.getOutputStream());
this.in = new BufferedReader(new InputStreamReader(this.session.getInputStream()));
this.dataIn = new DataInputStream(this.session.getInputStream());
}
public Client getClient() {
return this.client;
}
public byte[] readBytes() {
int len;
byte[] data = null;
try {
len = this.dataIn.readInt();
data = new byte[len];
if (len > 0) {
this.dataIn.readFully(data);
}
} catch (IOException e) {
e.printStackTrace();
}
return data;
}
public String readMessage() {
try {
return this.in.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public boolean isConnected() {
try {
this.in.read();
this.lastCheck = System.currentTimeMillis();
return true;
} catch (IOException e) {
if (!inConnection()) {
System.out.println("User disconnected");
try {
this.destruct();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
return false;
}
private boolean inConnection() {
return System.currentTimeMillis() - lastCheck < this.maxTime;
}
public void startClientService() throws IOException {
while(!this.session.isClosed()) {
if (System.currentTimeMillis() - this.checkTime > 600) {
System.out.println(System.currentTimeMillis() - this.checkTime);
if (this.isConnected()) {
int packetType = this.dataIn.readInt();
packets.getPacket(packetType);
}
}
}
}
public void destruct() throws IOException {
this.session.close();
this.connection.removeClient(this);
System.out.println("Session killed");
}
}
Thanks!
While I don't have time to look over all the code, here are two things that could help you out.
1) Use a defined message header. Define X number of bytes of each message that the client will send to the server. Use these bytes to define how long the message will be, and what type of message it is. The server knows the length and layout of this header, and uses it to process the message in a particular way. Example could be a header of one byte. A value of 1 could be a I'm connected message. 2 could be I'm about to disconnect. 3 could be I'm currently away, and 4 could be an incoming chat message.
2) There are 2 ways you can handle the input. First is to use blocking IO, and create a separate thread to receive messages from each client. I believe this is what you are currently doing. The second is to use non-blocking IO, and have a separate thread iterate over the open sockets and do a read. Non-blocking will check if there is data to read, but if there is not, the thread will continue executing.

send a file to a client after long wait

i've a java servlet that makes some reports. When a user choose a report it makes a query on a db and stream the xls report to the client. All in synchronous way. The problem is that sometimes i've a lot of records to fetch from the db and i would like to give a better user experience, allowing the user to do something else while the report is processing and popping out in some way the link when the process is finished. Is there a java library or some techniques to avoid the long waiting and achieve that goal?
Right now i've prepared a piece of code that in a asynchronous way completes the report and sends an email to the registered client, with the url from wich download the file, but it has to be replaced with something else because i can no longer communicate by email.
Thanks in advance
heres my take on this, i dont know of a single library that will exactly match you needs, youd probably need some custom development here.
I believe you have implemented async service that on completion sends
out an email for notification. Instead of sending out an email, let
that thread update a job table of some sort -- an entry in a db table
or some application/session scoped map.
Have a servlet/restful ws
expose that job table at some url. Poll the url at regular
intervals. Ajax poll is a standard feature in js libraries JQuery,
Prototype.
When you get a response that some report is complete, show
some popup or may be a facebook you-have-notification kind of thing
on the client side.
i have not considered authentication/authorization issues here, you need to take care of that as well.
Hope this helps
A multithreaded client server program to download my image files.
Since there are four files to download the client makes 4 connection attempts. This is not limited to 4 but the files sent by the FileServer will get repeated after the fourth attempt. The save dialog and file saving is done in different threads so as to not hamper the file downloading.
Here is the FileServer...
public class FileServer {
private final ExecutorService exec = Executors.newCachedThreadPool();
final String[] fileNames = {
"C:\\Users\\clobo\\Pictures\\Arpeggios\\Ex 1.jpg",
"C:\\Users\\clobo\\Pictures\\Arpeggios\\Ex 2.jpg",
"C:\\Users\\clobo\\Pictures\\Arpeggios\\Ex 3.jpg",
"C:\\Users\\clobo\\Pictures\\Arpeggios\\Ex 4.jpg"
};
public void start() throws IOException {
ServerSocket socket = new ServerSocket(7777);
System.out.println("Waiting for client message...");
while (!exec.isShutdown()) {
try {
for (final String fileName : fileNames){
final Socket conn = socket.accept();
exec.execute(new Runnable() {
public void run() {
sendFile(conn,fileName);
}
});
}
} catch (RejectedExecutionException e) {
if (!exec.isShutdown())
log("task submission rejected", e);
}
}
}
public void stop() {
System.out.println("Shutting down server...");
exec.shutdown();
}
private void log(String msg, Exception e) {
Logger.getAnonymousLogger().log(Level.WARNING, msg, e);
}
public void sendFile(Socket conn, String fileName) {
File myFile = new File(fileName);
if (!myFile.exists()) {
log("File does not exist!",null);
}
// file does exist
System.out.println(Thread.currentThread().getName());
System.out.println("AbsolutePath:" + myFile.getAbsolutePath());
System.out.println("length: " + myFile.length());
if (myFile.exists()) {
try {
ObjectOutputStream oos = new ObjectOutputStream(
conn.getOutputStream());
oos.writeObject(myFile);
oos.close();
} catch (IOException e) {
log("IOException Error", e);
e.printStackTrace();
}
}
}
public static void main(String[] args) throws IOException {
FileServer fs = new FileServer();
fs.start();
}
}
here is the FileServerClient...
public class FileServerClient {
private final ExecutorService exec = Executors.newCachedThreadPool();
Frame myFrame = new Frame();
List<File> fileList = new ArrayList<File>();
public void receiveFileFromServer() throws Exception{
Socket sock = null;
InputStream socketInputStream = null;
String host = "localhost";
int port = 7777;
for (int i=0;i<4;i++) {
sock = new Socket(host, port);
socketInputStream = sock.getInputStream();
System.out.println("Connection successful...");
// recieve the file
ObjectInputStream ois = new ObjectInputStream(socketInputStream);
// file from server is deserialized
final File myfile = (File) ois.readObject();
fileList.add(myfile);
// deserialized file properties
System.out.println("AbsolutePath: " + myfile.getAbsolutePath());
System.out.println("FileName:" + myfile.getName());
System.out.println("length" + myfile.length());
exec.execute(new Runnable() {
public void run() {
saveFile(myfile);
}
});
}
}
private void saveFile(File myfile) {
FileDialog fileDialog = new FileDialog(myFrame,
"Choose Destination for "+ myfile.getName(), FileDialog.SAVE);
fileDialog.setDirectory(null);
fileDialog.setFile("enter file name here");
fileDialog.setVisible(true);
String targetFileName = fileDialog.getDirectory()
+ fileDialog.getFile() + ".jpg";
System.out.println("File will be saved to: " + targetFileName);
copyBytes(myfile, targetFileName);
}
private void copyBytes(File originalFile, String targetFileName) {
try {
FileInputStream in = new FileInputStream(originalFile);
FileOutputStream out = new FileOutputStream(targetFileName);
int c;
while ((c = in.read()) != -1) {
out.write(c);
}
out.close();
in.close();
} catch (Exception e) {
log("IOException Error", e);
}
}
private void log(String msg, Exception e) {
Logger.getAnonymousLogger().log(Level.WARNING, msg, e);
}
public static void main(String[] args) throws Exception {
FileServerClient client = new FileServerClient();
client.receiveFileFromServer();
}
}
You could make an asynchronous request from the client. Lets assume that you client is an html page. When the user selects a report and clicks on 'submit' you could fire an ajax request with the report parameters (jquery can be useful for this). It would be good to keep a section on the user homepage that says something like 'prepared reports'. The client can then goto the prepared report section to download the report. As specified in the comments above, you may also have to implement a popup that informs the user that the requested report is ready. the popup is shown when the ajax requests returns successfully. However, the client may have logged out by the time the report finishes, so it may be a good idea to make the download link available again in the 'prepared reports' section when the user logs in.

Threads,Sockets and Streams

In my program I want to send some information to another computer with sockets. The first socket send some text throw the server and when the second socket receive this information it send a answer to the first socket. The problem is that another thread receive the answer and the only thing which I get is deadlock.
This is the server side:
else if(msgArray[0].compareTo("game_request") == 0){
if(userMap.containsKey(msgArray[1])){
Socket socketPlayerTwo = userMap.get(msgArray[1]);
otherPlayer = msgArray[1];
sendResult(socketPlayerTwo, "game_offer?"+username);
Boolean willPlay =Boolean.valueOf(recieveRequest(socketPlayerTwo).split("?")[1]);
if(willPlay)
playingUser.put(username,msgArray[1]);
sendResult(socket, "game_accept?"+willPlay);
}
}
This is the client side:
private void showGameRequest(String usernameOther) {
try{
int status = GameWindow.getInstance().showNotification("Game Offer","The user " + usernameOther + " offers you a game!\nDo you agree?",SWT.ICON_QUESTION|SWT.YES|SWT.NO);
if (status == SWT.YES){
otherPlayer = usernameOther;
sendRequest("send_message_to_user?user="+usernameOther+"&value=true");
GameWindow.getInstance().getDisplay().asyncExec(new Runnable() {
#Override
public void run() {
GameWindow.getInstance().startNewGame();
}
});
}
else
sendRequest("send_message_to_user?user="+usernameOther+"&value=false");
}
catch (IOException exc){
}
}
Here is the sendRequest method:
private void sendResult(Socket socket,String request) throws IOException{
DataOutputStream writer = new DataOutputStream(socket.getOutputStream());
writer.writeUTF(request);
writer.flush();
}
The client socket is created in the class Server
while (true) {
try {
Socket socket = serverSocket.accept();
new GameThread(socket,databaseManager);
} catch (IOException e) {
e.printStackTrace();
}
}
and it is put in hashmap when the user pass the login level:
if(msgArray[0].compareTo("user_info") == 0){
Integer flagUser = -1;
String[] userInfo = {msgArray[1].substring(msgArray[1].indexOf("=") + 1, msgArray[1].indexOf("&")),msgArray[1].substring(msgArray[1].lastIndexOf("=")+ 1, msgArray[1].indexOf(";"))};
Boolean status = databaseManager.checkUser(userInfo[0], userInfo[1]);
if(status){
if(!userMap.containsKey(userInfo[0])){
userMap.put(userInfo[0], socket);
username = userInfo[0];
flagUser = 0;
}
else
flagUser = 1;
}
sendResult(socket, "user_info_status?"+flagUser.toString()+"");
}
I thing I know what is the reason of the deadlock but I can't solve it. When the first user send the information to the other user he wait for response. Of course the other user send a response but this response is handle from other thread. So the deadlock is from a read method which block the thread. How can I send information from one socket to another without deadlock?
public GameThread(Socket socket, DatabaseManager databaseManager) {
this.socket = socket;
this.databaseManager = databaseManager;
parser = new RequestParser();
authorizationControl = new AuthorizationControl(databaseManager);
communication = new SocketCommunication(socket);
start();
}
Could you show us more of your code?
sendResult(socketPlayerTwo, "game_offer?"+username);
recieveRequest(socketPlayerTwo);
sendRequest("send_message_to_user?user="+usernameOther+"&value=true");
for starters.
Judging by the little i'm seeing you have a problem with the order in which you're using them. As far as i can tell you have a inputSteram.readObject() method that has blocked somewhere waiting for a message from the other side.

Categories