I'm making a app which can send a character ("B") to activate microcontroller then accept the result data from it. The data will be numbers 0-100. However I'm stuck in converting stream data to string.
I've tried the codes in comment but the process ended up being looping forever.
Here is my codes :
public Bluetooth(startover so, Handler handler, ProgressDialog pd) {
// TODO Auto-generated constructor stub
this.handler=handler;
activity=so;
this.pd=pd;
}
#Override
public void run() {
// TODO Auto-generated method stub
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mBluetoothAdapter.enable();
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
try
{
btSocket =device.createRfcommSocketToServiceRecord(MY_UUID);
//Toast.makeText(this, "Bluetooth_socket is created", Toast.LENGTH_LONG).show();
}
catch (Exception e)
{
Log.e(TAG, "ON RESUME: Socket creation failed.", e);
}
try
{
btSocket.connect();
Log.e(TAG, "ON RESUME: BT connection established, datatransfer link open.");
//Toast.makeText(this, "Bluetooth_socket is connected", Toast.LENGTH_LONG).show();
}
catch (Exception e)
{
try
{
btSocket.close();
}
catch (IOException e2)
{
Log.e(TAG, "ON RESUME: Unable to close socket during connection failure", e2);
}
}
message = "B";
sendMessage(message);
InputStream mInput=null;
try {
mInput = btSocket.getInputStream();
System.out.println("Input Open");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while(!Thread.currentThread().isInterrupted() && mBluetoothAdapter.isEnabled()) {
try {
int bytesAvailable = mInput.available();
if(bytesAvailable > 0) {
System.out.println("Pesan Diterima");
BufferedReader r = new BufferedReader(new InputStreamReader(mInput));
StringBuilder total = new StringBuilder(bytesAvailable);
String line;
//BACA LEBIH DARI 1 KARAKTER
//while ((line = r.readLine()) != null) {
// total.append(line);
//}
final String message=total.toString();
handler.post(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
pd.dismiss();
System.out.println("Turn "+message);
activity.startActivity(new Intent(activity.getApplicationContext(),result.class).putExtra("data", message));
}
});
break;
}
}
catch (IOException ex) {
}
}
super.run();
}
private void sendMessage (String message) {
byte[] send = message.getBytes();
try {
OutputStream OutStream = btSocket.getOutputStream();
OutStream.write(send);
System.out.println("Send "+message);
}
catch (IOException e) {
Log.e(TAG, "Exception during write", e);
}
}
}
Related
I have the following code in JAVA to create Server Socket to listen for incoming connections :
public class ConnectOracle {
public static void main(String[] args) {
String driver = "oracle.jdbc.driver.OracleDriver"; //
String serverName = "10.11.201.84";
String portNumber = "1521";
String db = "XE";
String url = "jdbc:oracle:thin:#" + serverName + ":" + portNumber + ":"
+ db; // connectOracle is the data
// source name
String user = "ORAP"; // username of oracle database
String pwd = "ORAP"; // password of oracle database
Connection con = null;
ServerSocket serverSocket = null;
Socket socket = null;
DataInputStream dataInputStream = null;
DataOutputStream dataOutputStream = null;
try {
Class.forName(driver);// for loading the jdbc driver
System.out.println("JDBC Driver loaded");
con = DriverManager.getConnection(url, user, pwd);// for
// establishing
// connection
// with database
Statement stmt = (Statement) con.createStatement();
serverSocket = new ServerSocket(8888);
System.out.println("Listening :8888");
while (true) {
try {
socket = serverSocket.accept();
System.out.println("Connection Created");
dataInputStream = new DataInputStream(
socket.getInputStream());
dataOutputStream = new DataOutputStream(
socket.getOutputStream());
System.out.println("ip: " + socket.getInetAddress());
// System.out.println("message: " +
// dataInputStream.readUTF());
ResultSet res=stmt.executeQuery("select * from food_category");
while(res.next()){
System.out.println(res.getString(1));
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (dataInputStream != null) {
try {
dataInputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (dataOutputStream != null) {
try {
dataOutputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
In my Android program I am trying to create a connection with this JAVA program . The code is as follows :
class ConnectToOracle extends AsyncTask<String, String, String> {
Socket socket = null;
DataOutputStream dataOutputStream = null;
DataInputStream dataInputStream = null;
#Override
protected void onPreExecute() {
super.onPreExecute();
;
}
// Download Music File from Internet
#Override
protected String doInBackground(String... f_url) {
try {
socket = new Socket("10.11.201.84", 8888);
dataOutputStream = new DataOutputStream(socket.getOutputStream());
dataInputStream = new DataInputStream(socket.getInputStream());
dataOutputStream.writeUTF(textOut.getText().toString());
textIn.setText(dataInputStream.readUTF());
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
if (socket != null){
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (dataOutputStream != null){
try {
dataOutputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (dataInputStream != null){
try {
dataInputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return null;
}
// Once Music File is downloaded
#Override
protected void onPostExecute(String file_url) {
// Dismiss the dialog after the Music file was downloaded
}
}
But the connection is not established . How can I establish connection ? Any advice is of great help .
I have an App that is receiving a video file from another App that is working as a Server. While the App is saving the file received on the socket, the video stream starts playing the file (which is under construction). In the code sample, after I press the btnStream, I press the btnPlay and App runs successfully. However, if the playing rate is greater than the download rate, an error will occur. I want to avoid this case. So I need to have a listener on the Video Playing that will pause the videoview when it predicts that this error will occur. I know a solution where if I know the video size, I can counter the bytes received and monitor how many seconds have been buffered and see if the videoview should pause or not. However, is it possible to do it without knowing the video file size? Or having two threads that depends on each other? Thanks.
Note: the VideoView used is a custom one where it can play FileDescriptor.
btnStream.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
String s = etURL.getText().toString();
String ip = "10.0.0.24";
int port = 7878;
mct= new VideoDownloadTask(ip,port);
mct.execute();
}});
final MediaController mediaController = new MediaController(this);
mediaController.setAnchorView(mVideoView);
Button btnPlay = (Button) findViewById(R.id.button2);
btnPlay.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
try {
mVideoView.setVideoFD((new FileInputStream(new File("/sdcard/tempVideo.mp4")).getFD()));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mVideoView.seekTo(0);
mVideoView.start();
}
});
}
public class VideoDownloadTask extends AsyncTask<Void, Void, Void> {
String dstAddress;
int dstPort;
String response = "";
Socket socket=null;
VideoDownloadTask(String addr, int port){
dstAddress = addr;
dstPort = port;
}
#Override
protected Void doInBackground(Void... arg0) {
try {
socket = new Socket(InetAddress.getByName(dstAddress), dstPort);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
try {
if(socket!=null)socket.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
File f = new File("/sdcard/tempVideo.mp4");
try {
f.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
DataInputStream in=null;
try {
in = new DataInputStream (socket.getInputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
FileOutputStream videoFile = null;
try {
videoFile = new FileOutputStream(f);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int len;
byte buffer[] = new byte[8192];
try {
while((len = in.read(buffer)) != -1) {
videoFile.write(buffer, 0, len);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
videoFile.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
Toast.makeText(getApplicationContext(), "Done Downloading File",
Toast.LENGTH_LONG).show();
super.onPostExecute(result);
}
}
}
I applied a simple solution that resolved the problem. I am sharing it if anyone is having the same problem. The solution was simply to add an error listener to the videoView that will block the error popups and pauses the video.
mVideoView.setOnErrorListener(new OnErrorListener(){
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
// TODO Auto-generated method stub
statusText.setText("ERROR PLAYING VIDEO");
mVideoView.pause();
return true;
}
});
pDialog = new ProgressDialog(PlayVideoActivity.this);
pDialog.setTitle("Gajacharitra");
pDialog.setMessage("Buffering video...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
try {
// Start the MediaController
mediacontroller.setAnchorView(mVideoView);
// Get the URL from String VideoURL
Uri video = Uri.parse(mVideoURL);
mVideoView.setMediaController(mediacontroller);
mVideoView.setVideoURI(video);
mVideoView.requestFocus();
mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
// Close the progress bar and play the video
public void onPrepared(MediaPlayer mp) {
pDialog.dismiss();
mVideoView.start();
}
});
mVideoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
#Override
public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {
mVideoView.pause();
pDialog.dismiss();
Toast.makeText(PlayVideoActivity.this, "Can't play this video.", Toast.LENGTH_LONG).show();
finish();
return true;
}
});
} catch (Exception e) {
/*Log.e("Error", e.getMessage());
e.printStackTrace();*/
pDialog.dismiss();
Toast.makeText(PlayVideoActivity.this, "Can't play this video.", Toast.LENGTH_LONG).show();
finish();
}
I am trying to connect my App to the bluetooth device and after that i am doing the functionality Read and Write. I am able to do connectivity and Write command to device. But i am not able to do Read functionality.
The "Read" functionality is like, as soon as device socket will get connect to the App, it should send the device information continuously. But i my case, read() method is calling but every time i am getting the length on InputStream in 0.
Below is the code what i am writing. Please check it where i am going wrong and please help me.
public class ConnectionThread implements Runnable {
private static final String CLASSTAG = ConnectionThread.class.getSimpleName();
public static BluetoothSocket mSocket;
private InputStream inStream;
private OutputStream outStream;
private boolean canceled = false;
private Context mContext;
public ConnectionThread(Context context, BluetoothDevice device) {
this.mContext = context;
try {
mSocket = device.createRfcommSocketToServiceRecord(UUID.fromString(Constants.mUUID));
} catch (IOException e) {
Log.e(CLASSTAG, "createRfcommSocketToServiceRecord", e);
}
}
#SuppressLint("NewApi")
#Override
public void run() {
// Cancel discovery because it will slow down the connection
if(BluetoothAdapter.getDefaultAdapter().isDiscovering()) {
BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
}
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mSocket.connect();
} catch (IOException e) {
Log.e(CLASSTAG, "connect failed", e);
// Unable to connect; close the socket and get out
disconnect();
return;
}
// Get the input and output streams, using temp objects because
// member streams are final
try {
inStream = mSocket.getInputStream();
outStream = mSocket.getOutputStream();
} catch (IOException e) {
Log.e(CLASSTAG, "IO streams init failed", e);
disconnect();
return;
}
while (!canceled) {
read();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
Log.e(CLASSTAG, "sleep failed", e);
}
}
}
#SuppressLint("NewApi")
public void applyCommand(String configCommand) throws IOException {
byte[] bytes = null;
bytes = new BigInteger(configCommand,16).toByteArray();
if (mSocket.isConnected()) {
//write(bytes);
outStream.write(bytes);
Log.d(CLASSTAG, "Command apply: " + bytes + " (" + configCommand + ")");
}
Toast.makeText(mContext, mContext.getString(R.string.cmd_updated), Toast.LENGTH_LONG).show();
}
private void read() {
byte[] buffer = new byte[128];
// Keep listening to the InputStream while connected
try {
// Read from the InputStream
if (inStream.available() > 0) {
int bytes = inStream.read(buffer);
if (bytes > 0) {
Log.d(CLASSTAG, "Response: " + new String(buffer, 0, bytes));
}
}
// Send the obtained bytes to the UI Activity
// mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer).sendToTarget();
} catch (IOException e) {
Log.e(CLASSTAG, "reading from input stream failed", e);
disconnect();
}
}
public void disconnect() {
try {
if (outStream != null) {
outStream.close();
}
if (inStream != null) {
inStream.close();
}
mSocket.close();
canceled = true;
} catch (IOException e) {
Log.e(CLASSTAG, "close socket", e);
}
}
}
UPDATE: ok so I kept trying to press send until I received the java.net.SocketException: sendto failed: EPIPE (Broken pipe) exception as a toast message once and then there was no activity once again when I pressed the send button. Meaning I didn't get the exception again.
I have two apps where one acts as the server and the other as a client. I was able to send a message from the server to the client like this
dataOutputStream.writeUTF("hello");
basically as a hardcoded string
but when I added a textfield and a button to the server app and tried listening to the onClick like this
sendChatbtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
try {
dataOutputStream.writeUTF(chatMsg);
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(ServerActivity.this, "An exception occurred: " + e.toString(), Toast.LENGTH_SHORT).show();
// TODO Auto-generated catch block
}
}
});
Absolutely NOTHING happened when I press the SEND button and the client did not receive any message, I don't even get any exception as a toast. By the way I am able to send messages from the client to the server and the server receives the client's messages but the client doesn't get any messages from the server.
The logcat although shows this:
08-09 04:13:45.694: E/LocSvc_adapter(761): E/virtual loc_api_adapter_err LocApiV02Adapter::injectPosition(double, double, float):632]: error! status = eLOC_CLIENT_FAILURE_INVALID_PARAMETER, inject_pos_ind.status = UNKNOWN
08-09 04:15:25.220: A/ActivityManager(761): Service ServiceRecord{42e78d58 u0 com.estrongs.android.pop/com.estrongs.android.ui.notification.ESTaskService} in process ProcessRecord{449c4320 9734:com.estrongs.android.pop/u0a245} not same as in map: null
08-09 04:16:06.444: E/AudioStreamOutALSA(269): PCM_Write set_amp_mode,1
Here's my Server code:
public class ServerActivity extends Activity {
TextView info, infoip, msg;
String message = "";
ServerSocket serverSocket;
EditText chatBoxText;
Button sendChatbtn, startGameBtn;
Socket socket = null;
DataInputStream dataInputStream = null;
DataOutputStream dataOutputStream = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_server_socket);
info = (TextView) findViewById(R.id.info);
infoip = (TextView) findViewById(R.id.infoip);
msg = (TextView) findViewById(R.id.msg);
chatBoxText=(EditText) findViewById(R.id.chatBox);
sendChatbtn=(Button) findViewById(R.id.sendChatButton);
startGameBtn=(Button) findViewById(R.id.startGamebutton);
infoip.setText(getIpAddress());
Thread socketServerThread = new Thread(new SocketServerThread());
socketServerThread.start();
}
#Override
protected void onDestroy() {
super.onDestroy();
if (serverSocket != null) {
try {
serverSocket.close();
closeSockets();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Toast.makeText(ServerActivity.this, "An exception occurred: " + e.toString(), Toast.LENGTH_SHORT).show();
}
}
}
private class SocketServerThread extends Thread {
static final int SocketServerPORT = 8080;
int count = 0;
String chatMsg = chatBoxText.getText().toString();
#Override
public void run() {
try {
serverSocket = new ServerSocket(SocketServerPORT);
ServerActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
info.setText("I'm waiting here: "
+ serverSocket.getLocalPort());
}
});
while (true) {
socket = serverSocket.accept();
dataInputStream = new DataInputStream(
socket.getInputStream());
dataOutputStream = new DataOutputStream(
socket.getOutputStream());
String messageFromClient = "";
//If no message sent from client, this code will block the program
messageFromClient = dataInputStream.readUTF();
count++;
message += "#" + count + " from " + socket.getInetAddress()
+ ":" + socket.getPort() + "\n"
+ "Msg from client: " + messageFromClient + "\n";
ServerActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
msg.setText(message);
}
});
sendChatbtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
try {
dataOutputStream.writeUTF(chatMsg);
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(ServerActivity.this, "An exception occurred: " + e.toString(), Toast.LENGTH_SHORT).show();
// TODO Auto-generated catch block
}
}
});
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Toast.makeText(ServerActivity.this, "An exception occurred: " + e.toString(), Toast.LENGTH_SHORT).show();
final String errMsg = e.toString();
ServerActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
msg.setText(errMsg);
}
});
}
}
}
private String getIpAddress() {
String ip = "";
try {
Enumeration<NetworkInterface> enumNetworkInterfaces = NetworkInterface
.getNetworkInterfaces();
while (enumNetworkInterfaces.hasMoreElements()) {
NetworkInterface networkInterface = enumNetworkInterfaces
.nextElement();
Enumeration<InetAddress> enumInetAddress = networkInterface
.getInetAddresses();
while (enumInetAddress.hasMoreElements()) {
InetAddress inetAddress = enumInetAddress.nextElement();
if (inetAddress.isSiteLocalAddress()) {
ip += "SiteLocalAddress: "
+ inetAddress.getHostAddress() + "\n";
}
}
}
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
ip += "Something Wrong! " + e.toString() + "\n";
Toast.makeText(ServerActivity.this, "An exception occurred: " + e.toString(), Toast.LENGTH_SHORT).show();
}
return ip;
}
public void closeSockets()
{
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Toast.makeText(ServerActivity.this, "An exception occurred: " + e.toString(), Toast.LENGTH_SHORT).show();
}
try {
dataInputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Toast.makeText(ServerActivity.this, "An exception occurred: " + e.toString(), Toast.LENGTH_SHORT).show();
}
try {
dataOutputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Toast.makeText(ServerActivity.this, "An exception occurred: " + e.toString(), Toast.LENGTH_SHORT).show();
}
}
}
Here's the Client Code:
public class ClientActivity extends Activity {
TextView textResponse;
EditText editTextAddress, editTextPort;
Button buttonConnect, buttonClear;
EditText welcomeMsg;
private MyClientTask myClientTask;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_client);
editTextAddress = (EditText) findViewById(R.id.address);
editTextPort = (EditText) findViewById(R.id.port);
buttonConnect = (Button) findViewById(R.id.connect);
buttonClear = (Button) findViewById(R.id.clear);
textResponse = (TextView) findViewById(R.id.response);
welcomeMsg = (EditText)findViewById(R.id.welcomemsg);
buttonConnect.setOnClickListener(buttonConnectOnClickListener);
buttonClear.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
textResponse.setText("");
}
});
}
OnClickListener buttonConnectOnClickListener = new OnClickListener() {
#Override
public void onClick(View arg0) {
String tMsg = welcomeMsg.getText().toString();
if(tMsg.equals("")){
tMsg = null;
Toast.makeText(ClientActivity.this, "No Welcome Msg sent", Toast.LENGTH_SHORT).show();
}
MyClientTask myClientTask = new MyClientTask(editTextAddress
.getText().toString(), Integer.parseInt(editTextPort
.getText().toString()),
tMsg);
myClientTask.execute();
}
};
public class MyClientTask extends AsyncTask<Void, Void, Void> {
String dstAddress;
int dstPort;
String response = "";
String msgToServer;
Socket socket = null;
DataOutputStream dataOutputStream = null;
DataInputStream dataInputStream = null;
MyClientTask(String addr, int port, String msgTo) {
dstAddress = addr;
dstPort = port;
msgToServer = msgTo;
}
#Override
protected Void doInBackground(Void... arg0) {
try {
socket = new Socket(dstAddress, dstPort);
dataOutputStream = new DataOutputStream(
socket.getOutputStream());
dataInputStream = new DataInputStream(socket.getInputStream());
if(msgToServer != null){
dataOutputStream.writeUTF(msgToServer);
}
response = dataInputStream.readUTF();
} 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();
}
return null;
}
protected void CloseSockets()
{
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
dataOutputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
dataInputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
protected void onPostExecute(Void result) {
textResponse.setText(response);
super.onPostExecute(result);
}
}
protected void onDestroy()
{
myClientTask.CloseSockets();
super.onDestroy();
}
}
You are not updating the chatMsg string after the onClick, so it initializes as a zero length string, and does not change.
When onClick occurs, you need to get the current string from your TextView:
#Override
public void onClick(View v) {
// add this!!!
chatMsg = chatBoxText.getText().toString();
try {
dataOutputStream.writeUTF(chatMsg);
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(ServerActivity.this, "An exception occurred: " + e.toString(), Toast.LENGTH_SHORT).show();
// TODO Auto-generated catch block
}
}
I write some client-server communication.
My server:
public class Server {
public synchronized static void sendPacket(Packet packet,
ObjectOutputStream server) {
try {
server.writeObject(packet);
server.flush();
} catch (IOException e) {
Log.d(TAG, "Error while sending a packet. Output stream is unaviable.");
}
}
public synchronized static Packet readPacket(ObjectInputStream sourceStream) {
Packet recivedPacket = null;
try {
recivedPacket = (Packet) sourceStream.readObject();
} catch (StreamCorruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return recivedPacket;
}
/** Register user on the server */
private User registerUser(Socket socket) {
ClientUserLoginPacket newUserPacket = null;
ObjectInputStream ois = null;
ObjectOutputStream oos = null;
try {
Log.i(TAG, "Opening output stream...");
oos = new ObjectOutputStream(socket.getOutputStream());
if (oos != null)
Log.d(TAG, "Output stream opened");
Log.i(TAG, "Opening input stream...");
ois = new ObjectInputStream(socket.getInputStream());
if (ois != null)
Log.d(TAG, "Input stream opened");
} catch (StreamCorruptedException e1) {
Log.e(TAG, "Error while opening stream");
} catch (IOException e1) {
e1.printStackTrace();
}
// First packet MUST be register request
try {
Log.d(TAG, "Waiting for login packet from client...");
newUserPacket = (ClientUserLoginPacket) readPacket(ois);
Log.d(TAG, "Login packet from recived...");
} catch (Exception e) {
Log.e(TAG, "Can't recive login packet.");
}
User newUserInstance = null;
// TODO check if exists. or to map in the future
if (newUserPacket != null) {
newUserInstance = new User(socket, ois, oos, newUserPacket.nick);
users.add(newUserInstance);
Log.d(TAG, "User " + newUserPacket.nick + " registered.");
Server.sendPacket(new ServerLoginAcceptedPacket(), oos);
Log.d(TAG, "User accept confirmation sent.");
}
return newUserInstance;
}
#Override
public void run() {
Log.i(TAG, "Starting server...");
ServerSocket server;
try {
server = new ServerSocket(PORT);
Log.i(TAG, "Server started.");
server.setSoTimeout(0);
while (true) {
Log.i(TAG, "Waiting for players...");
final Socket socket = server.accept();
Log.i(TAG, "New player connected.");
new Thread(new Runnable() {
#Override
public void run() {
Log.i(TAG, "Try to register new player.");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
User user = registerUser(socket);
while (true) {
Log.i(TAG, "Waiting for packets from " + user.nick+"...");
Packet packet = readPacket(user.ois);
Log.i(TAG, "Packet from " + user.nick + " recived.");
if (packet instanceof ...) {
...
}
}
}
}).start();
}
} catch (IOException e) {
Log.i(TAG, "Port is busy.");
}
}
private class User {
public Socket connection;
public ObjectInputStream ois;
public ObjectOutputStream oos;
public String nick;
public boolean inGame;
public User(Socket socket, ObjectInputStream ois,
ObjectOutputStream oos, String nick) {
this.connection = socket;
this.ois = ois;
this.oos = oos;
this.nick = nick;
}
// ...
}
My client:
public class Client {
callbackHandler = new Thread(new Runnable() {
#Override
public void run() {
while (true) {
Log.e(TAG, "Waiting for incomeing packets...");
Packet packet = (Packet) Server.readPacket(serverInput);
Log.e(TAG, "Packet recived.");
if (packet instanceof ServerLoginAcceptedPacket) {
Log.e(TAG, "Recived packet is "
+ packet.getClass().toString());
Intent intent = new Intent(MyActivity.this,
MainMenuActivity.class);
MyActivity.this.startActivity(intent);
}
}
}
});
public void connectToServer() {
SocketAddress sockaddr = new InetSocketAddress(mEditTextIp.getText()
.toString(), Server.PORT);
server = new Socket();
try {
server.setSoTimeout(1000);
Log.d(TAG, "Connecting to server.");
server.connect(sockaddr, Server.PORT);
Log.d(TAG, "Connected to server.");
} catch (IOException e) {
Log.e(TAG, "Can't connect to server.");
server = null;
}
if (server != null)
try {
server.setSoTimeout(0);
Log.d(TAG, "Opening output stream...");
serverOutput = new ObjectOutputStream(server.getOutputStream());
if (serverOutput != null)
Log.d(TAG, "Output stream opened");
else
Log.e(TAG, "Error while opening output stream");
} catch (IOException e) {
Log.e(TAG, "Server socket probably closed");
}
}
public void requestLogin() {
new Thread(new Runnable() {
#Override
public void run() {
Log.e(TAG, "Sending login packet...");
Server.sendPacket(new ClientUserLoginPacket(mEditTextLogin
.getText().toString(), ""), serverOutput); // TODO send
// pass and
// email
Log.e(TAG, "Login packet send");
}
}).start();
}
public void authenticate(View v) {
if (server == null)
connectToServer();
if (server != null) {
requestLogin();
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
serverInput = new ObjectInputStream(server.getInputStream());
} catch (StreamCorruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if (serverInput != null) {
Log.e(TAG, "Start reciving callbacks...");
callbackHandler.start();
} else {
Log.d(TAG, "Can't open input stream to server.");
}
}
}
public void runServer(View v) {
new Thread(new Server()).start();
Toast.makeText(this, "Server running...", 1000).show();
}
}
Where runServer() and authenticate() functions are triggered with button.
Problem is that after server recive ClientLoginPacket, all subsequent sentPacket functions hangs on oos.writeObject().
I think the order of reading/writing from/to streams may be wrong.
What should be correct order of opening streams and writing objects to them?
Do I have to write something to ObjectOutputStream before opening ObjectInputStream?
After few hours I found that keywords synchronized before my methods readPacket() and sendPacket() were problem. ;)