Closing clients on a multithreaded chat server - java

i am currently working on a chat server as a project an need a bit of help. i have a multithreaded chat server where i want the clients to be able to close their chat window without crashing the server because it loses connection. So far so good. i have a working gui, and when i have a single client logged in to the server it works just fine to close the window and so closing the clientIOProcessor without the server crashing.
However, when i have multiple clients logged in to the server and want to close one of them the hole thing crashes
here is the ClientIOProcessor:
public class ClientIOProcessor extends Object implements Runnable, InputListener {
private ObjectInput socketInput;
private ObjectOutput socketOutput;
private boolean keepRunning;
private ClientModelDistributor assignedModelDistributor;
private MessageImplementation currentMessage;
private UserHub userHub;
public ClientIOProcessor(ClientModelDistributor _assignedModelDistributor, ObjectInput _socketInput,
ObjectOutput _socketOutput) {
this.assignedModelDistributor = _assignedModelDistributor;
this.socketInput = _socketInput;
this.socketOutput = _socketOutput;
assignedModelDistributor.getInputHandler().registerInputListener(this);
keepRunning = true;
}
public ClientIOProcessor(ClientLoginProcessor clientLoginProcessor, UserHub userHub) {
assignedModelDistributor = clientLoginProcessor.assignedModelDistributor;
socketInput = clientLoginProcessor.socketInput;
socketOutput = clientLoginProcessor.socketOutput;
assignedModelDistributor.getInputHandler().registerInputListener(this);
assignedModelDistributor.getIncomingMessageHandler().addIncomingMessageListener(userHub);
keepRunning = true;
this.userHub = userHub;
}
public void run() {
while (keepRunning) {
currentMessage = null;
currentMessage = buildMessageFromInput();
if(currentMessage == null) return;
switch (currentMessage.getMessageType()) {
case CHATMSG:
assignedModelDistributor.getIncomingMessageHandler().enterMessage(currentMessage);
break;
case USRJOINED:
assignedModelDistributor.getIncomingMessageHandler().enterMessage(currentMessage);
break;
case USRLEFT:
assignedModelDistributor.getIncomingMessageHandler().enterMessage(currentMessage);
break;
case TERMINATE:
this.terminateConnection();
break;
default:
System.out.println("An error occurred.");
}
}
}
public void terminateConnection() {
keepRunning = false;
assignedModelDistributor.getIncomingMessageHandler().removeIncomingMessageListener(this.userHub);
assignedModelDistributor.getInputHandler().removeInputListener(this);
try {
socketInput.close();
socketOutput.close();
} catch (IOException e) {
e.printStackTrace();
}
// System.exit(0);
}
private MessageImplementation buildMessageFromInput() {
MessageImplementation messageSentByServer = null;
try {
messageSentByServer = (MessageImplementation) socketInput.readObject();
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
}
return messageSentByServer;
}
/**
* This method can be used to send <code>messages</code> to the server.
*
* #param message
* #throws IOException
*/
public void send(Message message) throws IOException {
try {
socketOutput.writeObject(message);
socketOutput.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* This method is called whenever the user enters input to this
* <code>InputListener</code>'s corresponding <code>InputHandler</code>.
*/
#Override
public void inputEntered(String input) {
try {
send(assignedModelDistributor.buildUserMessage(input));
} catch (IOException e) {
e.printStackTrace();
}
}
}
the clientIO processor gets the TERMINATE message from the server and calls the terminateConnection() Method to end the Streams.
Here is the ServerIOProcessor:
public class ServerIOProcessor implements Runnable, IncomingMessageListener {
private ServerModelDistributor assignedModelDistributor;
private User assignedUser;
private boolean keepRunning;
private ObjectInputStream socketInput;
private ObjectOutputStream socketOutput;
private MessageImplementation currentMessage;
private final String SYSTEM = "System";
public ServerIOProcessor(User _assignedUser, ObjectOutputStream _socketOutput, ObjectInputStream _socketInput,
ServerModelDistributor _assignedModelDistributor) {
assignedUser = _assignedUser;
socketInput = _socketInput;
socketOutput = _socketOutput;
assignedModelDistributor = _assignedModelDistributor;
keepRunning = true;
assignedModelDistributor.getIncomingMessageHandler().addIncomingMessageListener(this);
}
public void run() {
while (keepRunning) {
currentMessage = null;
currentMessage = buildMessageFromInput();
switch (currentMessage.getMessageType()) {
case CHATMSG:
assignedModelDistributor.getIncomingMessageHandler().enterMessage(currentMessage);
break;
case NEWTASK:
createNewTask();
break;
case TASKASSGNMNT:
assignTaskToUser();
break;
case NEWLEADER:
determineLeaderOfTeam();
break;
case ADDTEAM:
addTeam();
break;
case RMVTEAM:
removeTeam();
break;
case ADDTEAMMEMBER:
addUserToTeam();
break;
case RMVTEAMMEMBER:
removeUserFromTeam();
break;
case JOINTEAM:
joinTeam();
break;
case LEAVETEAM:
leaveTeam();
break;
case EDITDETAILS:
editUserDetails();
break;
case TERMINATE:
assignedModelDistributor.getIncomingMessageHandler().enterMessage(currentMessage);
letClientLeaveServer();
break;
default:
send(newSystemMessage(MessageType.ERROR));
System.out.println("An error occured in one of the server's active IO processes.");
break;
}
}
}
private void createNewTask() {
}
private void assignTaskToUser() {
// TODO Auto-generated method stub
}
private void determineLeaderOfTeam() {
// TODO Auto-generated method stub
}
private void addTeam() {
// TODO Auto-generated method stub
}
private void removeTeam() {
// TODO Auto-generated method stub
}
private void addUserToTeam() {
// TODO Auto-generated method stub
}
private void removeUserFromTeam() {
// TODO Auto-generated method stub
}
private void joinTeam() {
// TODO Auto-generated method stub
}
private void leaveTeam() {
// TODO Auto-generated method stub
}
private void editUserDetails() {
// TODO Auto-generated method stub
}
private void letClientLeaveServer() {
// TODO Auto-generated method stub
assignedModelDistributor.getIncomingMessageHandler().removeIncomingMessageListener(this);
try {
socketInput.close();
socketOutput.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
keepRunning = false;
}
private MessageImplementation buildMessageFromInput() {
MessageImplementation messageSentByUser = null;
try {
messageSentByUser = (MessageImplementation) socketInput.readObject();
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
}
return messageSentByUser;
}
private MessageImplementation newSystemMessage(MessageType msgtype) {
return new MessageImplementation(SYSTEM, msgtype);
}
//TODO Check expected purpose of this method.
/**
* This method is called whenever a <code>Message</code> is entered to the
* corresponding <code>IncomingMessageHandler</code>.
*/
#Override
public void messageEntered(Message message) {
// assignedModelDistributor.getIncomingMessageHandler().enterMessage(message);
try {
socketOutput.writeObject(message);
socketOutput.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* Writes the given <code>Message</code> to the Socket's
* <code>ObjectInputStream</code>.
*
* #throws IOException
*/
void send(Message message) {
try {
socketOutput.writeObject(message);
socketOutput.flush();
} catch (Exception r) {
System.out.println("Error!");
r.printStackTrace();
}
}
}
the important part here is the letClientLeaveServer() method to end the streams here as well. however, i think this is the wrong way, because i think this ends the Input/Ouput Streams for all logged in Clients.
The ServerSocket it self is initialized in another class ConnectionProcessor which starts the Socket on a given port and accepts it. then the connectionProcessor starts the serverLogInProcessor which starts a new Thread for the serverIOProcessor.
Here the ConnectionProcessor:
public class ConnectionProcessor implements Runnable {
private ServerModelDistributor assignedModelDistributor;
private boolean keepRunning;
private ServerSocket serverSocket;
private int assignedPort;
public ConnectionProcessor(int _assignedPort, ServerModelDistributor _assignedModelDistributor) {
assignedModelDistributor = _assignedModelDistributor;
assignedPort = _assignedPort;
keepRunning = true;
try {
serverSocket = new ServerSocket(assignedPort);
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void run() {
while (keepRunning) {
if(serverSocket.isClosed()) {
try {
serverSocket = new ServerSocket(assignedPort);
} catch (IOException e) {
e.printStackTrace();
}
}
try {
Socket socketCreatedForLoginProcess = serverSocket.accept();
serverSocket.close();
Thread serverLoginProcessor = new Thread(
new ServerLoginProcessor(this, socketCreatedForLoginProcess, assignedModelDistributor),
"loginProcess");
serverLoginProcessor.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

Related

Socket blocking client when sending image

So I'm making a simple chat where I'm sending content in the form of objects, in this case my problem is that when I'm sending and Image it just blocking my Client!, here's my shortened code.
I've isolated it mostly to the code below, as I've tested the rest and worked fine, I've also tried debugging this but I just can't seem to find the problem
Image
package com.example.mtc.Packets;
import java.io.Serializable;
public class Image extends Message implements Serializable {
/**
*
*/
private static final long serialVersionUID = -3188407715959746920L;
private byte[] content;
private String type;
public Image(byte[] content,String type, int sourceID,int destinationID,String sourceUsername) {
super(destinationID,sourceID,sourceUsername);
this.content = content;
this.type = "." + type;
}
public byte[] getContent() {
return content;
}
public String getType() {
return type;
}
}
ClientReaderThread:
while (true) {
try {
inputData = in.readObject();
if (inputData.getClass().getName().equals("com.example.mtc.Packets.Image")) {
Image imagePacket = (Image) inputData;
byte[] imageContent = imagePacket.getContent();
ImageIcon imageIcon = new ImageIcon(imageContent);
imageIcon.setImage(imageIcon.getImage().getScaledInstance(300, 300, java.awt.Image.SCALE_DEFAULT));
if (imagePacket.getDestinationID() == 0) {
if (Cliente.selectedChat == 0) {
Style style = chatCard.doc.addStyle("StyleName", null);
StyleConstants.setIcon(style, imageIcon);
chatCard.doc.insertString(chatCard.doc.getLength(), "ignored text\n", style);
chatCard.textPane.setCaretPosition(chatCard.textPane.getDocument().getLength());
Cliente.gui.revalidate();
}
} else if (imagePacket.getSourceID() == Cliente.selectedChat
|| imagePacket.getSourceID() == Cliente.getUserID()) {
Style style = chatCard.doc.addStyle("StyleName", null);
StyleConstants.setIcon(style, imageIcon);
chatCard.doc.insertString(chatCard.doc.getLength(), "ignored text\n", style);
chatCard.textPane.setCaretPosition(chatCard.textPane.getDocument().getLength());
Cliente.gui.revalidate();
}
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
JOptionPane.showMessageDialog(Cliente.gui, "Couldn't connect to Server!", "Error",
JOptionPane.ERROR_MESSAGE);
System.exit(1);
} catch (BadLocationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Server Listener
private void Listener() {
// TODO Auto-generated method stub
while (connected) {
inputData = readObject();
if (inputData != null) {
if (inputData.getClass().getName().equals("com.example.mtc.Packets.Image")) {
Image imagePacket = (Image) inputData;
byte[] imageContent = imagePacket.getContent();
ImageIcon imageIcon = new ImageIcon(imageContent);
imageIcon.setImage(imageIcon.getImage().getScaledInstance(300, 300,
java.awt.Image.SCALE_DEFAULT));
imageIcon.getImage().flush();
BufferedImage bi = new BufferedImage(
imageIcon.getIconWidth(),
imageIcon.getIconHeight(),
BufferedImage.TYPE_INT_RGB);
Graphics g = bi.createGraphics();
// paint the Icon to the BufferedImage.
imageIcon.paintIcon(null, g, 0,0);
g.dispose();
try {
File imageFile = File.createTempFile("image", imagePacket.getType(),
new File("./serverImages/"));
insertLog(imageFile.getAbsolutePath(), imagePacket.getDestinationID(), true);
new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
try {
Files.write(imageFile.toPath(), imageContent);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (imagePacket.getDestinationID() == 0) {
synchronized (Server.Threads) {
for (ClientHandler t : Server.Threads) {
if (!idExistsInBlockedList(t.getUserID(), userID)) {
t.sendObject(imagePacket);
}
}
}
} else {
synchronized (Server.Threads) {
for (ClientHandler t : Server.Threads) {
if (!idExistsInBlockedList(t.getUserID(), userID)) {
if (t.getUserID() == imagePacket.getDestinationID()) {
t.sendObject(imagePacket);
}
}
}
sendObject(imagePacket);
}
}
}
}
}
}
Managed to solve it by using SwingUtilities.invokeLater(), as advised by R.L.M

place call using Java with connected USB or HSDPA Dongle

i couldn't find any article upon "place call using java with a HSDPA Dongle" on google. i have done port initialization but don't know what to do for placing call.
1) i am using Huawei Dongle.
2) I have found error "NO CARRIER".
3) i am using the following code to detect port or modem and trying to place call but its giving me "NO CARRIER" error ! what mistake i am doing here kindly help me please
import java.io.*;
import java.util.*;
import gnu.io.*;
import java.io.*;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import org.apache.log4j.chainsaw.Main;
import sun.audio.*;
public class GSMConnect implements SerialPortEventListener,
CommPortOwnershipListener {
private static String comPort = "COM6"; // This COM Port must be connect with GSM Modem or your mobile phone
private String messageString = "";
private CommPortIdentifier portId = null;
private Enumeration portList;
private InputStream inputStream = null;
private OutputStream outputStream = null;
private SerialPort serialPort;
String readBufferTrial = "";
/** Creates a new instance of GSMConnect */
public GSMConnect(String comm) {
this.comPort = comm;
}
public boolean init() {
portList = CommPortIdentifier.getPortIdentifiers();
while (portList.hasMoreElements()) {
portId = (CommPortIdentifier) portList.nextElement();
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
if (portId.getName().equals(comPort)) {
System.out.println("Got PortName");
return true;
}
}
}
return false;
}
public void checkStatus() {
send("AT+CREG?\r\n");
}
public void dial(String phoneNumber) {
try {
//dial to this phone number
messageString = "ATD" + phoneNumber + ";\r\n";
outputStream.write(messageString.getBytes());
System.out.println("Called ");
} catch (IOException e) {
e.printStackTrace();
}
}
public void send(String cmd) {
try {
outputStream.write(cmd.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
public void sendMessage(String phoneNumber, String message) {
char quotes ='"';
send("AT+CMGS="+quotes + phoneNumber +quotes+ "\r\n");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// send("AT+CMGS=\""+ phoneNumber +"\"\r\n");
send(message + '\032');
System.out.println("Message Sent");
}
public void hangup() {
send("ATH\r\n");
}
public void welcomeMessage(){
// open the sound file as a Java input stream
String gongFile = "C:\\Users\\SACHIN\\Desktop\\7001110.mp3";
InputStream in;
try {
in = new FileInputStream(gongFile);
// create an audiostream from the inputstream
// AudioStream audioStream = new AudioStream(in);
// play the audio clip with the audioplayer class
// AudioPlayer.player.start(audioStream);
Clip clip = AudioSystem.getClip();
AudioInputStream inputStream = AudioSystem.getAudioInputStream(
Main.class.getResourceAsStream(gongFile));
clip.open(inputStream);
clip.start();
} catch (IOException | UnsupportedAudioFileException | LineUnavailableException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void connect() throws NullPointerException {
if (portId != null) {
try {
portId.addPortOwnershipListener(this);
serialPort = (SerialPort) portId.open("MobileGateWay", 2000);
serialPort.setSerialPortParams(115200,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
} catch (PortInUseException | UnsupportedCommOperationException e) {
e.printStackTrace();
}
try {
inputStream = serialPort.getInputStream();
outputStream = serialPort.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
try {
/** These are the events we want to know about*/
serialPort.addEventListener(this);
serialPort.notifyOnDataAvailable(true);
serialPort.notifyOnRingIndicator(true);
} catch (TooManyListenersException e) {
e.printStackTrace();
}
//Register to home network of sim card
send("ATZ\r\n");
} else {
throw new NullPointerException("COM Port not found!!");
}
}
public void serialEvent(SerialPortEvent serialPortEvent) {
switch (serialPortEvent.getEventType()) {
case SerialPortEvent.BI:
case SerialPortEvent.OE:
case SerialPortEvent.FE:
case SerialPortEvent.PE:
case SerialPortEvent.CD:
case SerialPortEvent.CTS:
case SerialPortEvent.DSR:
case SerialPortEvent.RI:
System.out.println("Ringing");
/*try {
Thread.sleep(5000);
send("ATA");
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}*/
break;
case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
case SerialPortEvent.DATA_AVAILABLE:
byte[] readBuffer = new byte[2048];
try {
while (inputStream.available() > 0)
{
int numBytes = inputStream.read(readBuffer);
System.out.print(numBytes);
if((readBuffer.toString()).contains("RING")){
System.out.println("Enter Inside if RING Loop");
welcomeMessage();
}
}
//readBufferTrial=readBufferTria;//+new String(readBuffer)+new Date();
//print response message
System.out.print(new String(readBuffer));
} catch (IOException e) {
}
break;
}
}
public void outCommand(){
System.out.print(readBufferTrial);
}
public void ownershipChange(int type) {
switch (type) {
case CommPortOwnershipListener.PORT_UNOWNED:
System.out.println(portId.getName() + ": PORT_UNOWNED");
break;
case CommPortOwnershipListener.PORT_OWNED:
System.out.println(portId.getName() + ": PORT_OWNED");
break;
case CommPortOwnershipListener.PORT_OWNERSHIP_REQUESTED:
System.out.println(portId.getName() + ": PORT_INUSED");
break;
}
}
public void closePort(){
serialPort.close();
}
public static void main(String args[]) {
GSMConnect gsm = new GSMConnect(comPort);
if (gsm.init()) {
try {
System.out.println("Initialization Success");
gsm.connect();
Thread.sleep(5000);
gsm.checkStatus();
Thread.sleep(5000);
System.out.println("Before Auto Answer");
gsm.send("ATS0=1");
Thread.sleep(1000);
gsm.dial("87SSSXXX9105");
// Thread.sleep(1000);
// gsm.welcomeMessage();
// Thread.sleep(1000);
// gsm.welcomeMessage();// for turning on Echo ATE1&W
Thread.sleep(20000);
gsm.hangup();
Thread.sleep(1000);
gsm.closePort();
gsm.outCommand();
System.exit(1);
} catch (Exception e) {
e.printStackTrace();
}
} else {
System.out.println("Can't init this card");
}
}
}
First you have to check if your HSDPA dongle really supports calls. A lot of HSDPA sticks only support SMS and data.
If it does and you have e.g. a virtual serial port you can connect from your Java program to it using e.g. Java RXTX and send AT-Commands like ATDT01234567 (dial 01234567) to the stick.

how to update my jframe in a server_client game?

I'm working on a server-client game in which I need to update client's JFrame from the server in a specific period.this is my game
The problem is that the client's JFrame does not update.to be sure,I have rendered the JFrame Submitted by the server and it's OK,but the client's JFrame does not change at all.Here's my code:
my server:
public class main implements java.io.Serializable{
static ArrayList<Socket> allsockets = new ArrayList<>();
static ArrayList<ObjectOutputStream> oos = new ArrayList<>();
static final MainFrame frame=new MainFrame();
static boolean testfirst=false;
private static final long serialVersionUID = 1L;
public static void main(String[] args) {
// TODO Auto-generated method stub
String name;
String color;
Color color1 = null;
Socket clientsocket=null;
ServerSocket serversocket=null;
PrintStream os = null;
ObjectInputStream is=null;
try{
serversocket = new ServerSocket(); // don't bind just yet
serversocket.setReuseAddress(true);
serversocket.bind(new InetSocketAddress(5555)); // can bind with reuse= true
}
catch(IOException e){
System.out.println(e);
}
while(true){
try {
clientsocket=serversocket.accept();
allsockets.add(clientsocket);
oos.add(new ObjectOutputStream(clientsocket.getOutputStream()));
is=new ObjectInputStream(clientsocket.getInputStream());
os = new PrintStream(clientsocket.getOutputStream());
try {
name =(String) is.readObject();
color=(String) is.readObject();
try {
java.lang.reflect.Field field = Class.forName("java.awt.Color").getField(color);
color1 = (Color)field.get(null);
} catch (Exception e) {
color = null;
}
player p=new player();
frame.addplayer(name, color1,p);
if(!testfirst){
testfirst=true;
new Thread(){
public void run(){
Timer timer=new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
// TODO Auto-generated method stub
System.out.println("timer works");
for(ObjectOutputStream os:oos){
try {
os.writeObject(frame);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}, 1, 1);
}
}.start();
}
handle h= new handle(is, frame, p);
h.start();
} catch (ClassNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
my client:
public class client implements java.io.Serializable {
static private final Lock mutex = new ReentrantLock(true);
private static final long serialVersionUID = 1L;
static double prevx =0;
static double prevy=0;
static Timer timer=new Timer();
static ObjectOutputStream os =null;
public static void main(String[]args) {
MainFrame frame=new MainFrame();
Socket clientSocket=null;
ObjectInputStream is=null;
String name;
String color;
try {
clientSocket = new Socket("localhost", 5555);
os = new ObjectOutputStream(clientSocket.getOutputStream());
is=new ObjectInputStream(clientSocket.getInputStream());
System.out.println("enter your name:");
Scanner in1=new Scanner(System.in);
name=in1.nextLine();
System.out.println("enter your color:");
color=in1.nextLine();
in1.close();
os.writeObject(name);
os.writeObject(color);
refresh ref=new refresh( is, os);
ref.start();
} catch (UnknownHostException e) {
System.err.println("Don't know about host");
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to host");
}
}}
the refresh class(which has the responsibility to update client's JFrame)
public class refresh extends Thread{
MainFrame frame;
ObjectInputStream ois;
ObjectOutputStream oos;
Timer timer=new Timer();
double prevx,prevy;
private Lock mutex = new ReentrantLock(true);
public refresh(ObjectInputStream ois,ObjectOutputStream oos){
frame=new MainFrame();
this.ois=ois;
this.oos=oos;
}
public void run(){
while(true){
try {
frame= (MainFrame) ois.readObject();
frame.repaint();
frame.removeMouseMotionListener(mml);
frame.addMouseMotionListener(mml);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setFocusable(true);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
MouseMotionListener mml=new MouseMotionListener() {
#Override
public void mouseMoved(MouseEvent arg0) {
// TODO Auto-generated method stub
mutex.lock();
try {
System.out.println("mouse moved");
oos.writeObject(arg0.getX());
oos.writeObject(arg0.getY());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mutex.unlock();
}
#Override
public void mouseDragged(MouseEvent arg0) {
// TODO Auto-generated method stub
}
};}
and if needed the handle class(which receives the mouse coordinates from the client)
public class handle extends Thread{
double prevx,prevy;
MainFrame frame;
player myplayer;
ObjectInputStream ois;
double screenwidth,screenheigth;
boolean first=false;
boolean finished = false;
static private final Lock mutex = new ReentrantLock(true);
Thread movethread = new Thread(){
public void run(){
System.out.println("movethread run");
try {
if(Math.abs(prevx-myplayer.xcenter)>1 || Math.abs(prevy - myplayer.ycenter)>1){
while(Math.abs(prevx-myplayer.xcenter)!=0
|| Math.abs(prevy - myplayer.ycenter)!=0){
if(prevx<0 || prevx>screenwidth || prevy<0 || prevy>screenheigth)break;
myplayer.movem(prevx, prevy,mutex);
frame.repaint();
System.out.println(myplayer.cp.getCenter());
}
finished = true;
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}};
public handle(ObjectInputStream ois,MainFrame frame,player p) {
// TODO Auto-generated constructor stub
this.myplayer=p;
this.ois=ois;
this.frame=frame;
this.screenwidth=frame.getscreenwidth();
this.screenheigth=frame.getscreenheigth();
}
public void run(){
System.out.println("handle thread run");
while(true){
try {
System.out.println("in handle");
System.out.println(first);
prevx= (double) ois.readObject();
prevy=(double) ois.readObject();
if(!first){
System.out.println("movethread started");
movethread.start();
first = true;
}
else if(first && finished){
movethread.run();
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void update(double x,double y){
this.prevx=x;
this.prevy=y;
}}
Any help would be appreciated.

Windows Console redirecting

I'm trying to write a program, which starts an process for the windows console (cmd) and redirects the Input,Output and Errorstreams to System.in/out/err. Also, if the process is closed (via the command exit) my program should shutdown.
I've written a solution, that works kind of. The only problem is my used thread don't notice the process is shutted down. Also I don't know if it is nessecery to write a new Thread for all this streams, so if you know an easier solution to redirect the streams I'd like to hear about it.
Here my SSCCE:
public class Main {
public static boolean run = true;
public static void main(String[] args) throws IOException {
ProcessBuilder p = new ProcessBuilder("cmd");
final Process pr = p.start();
new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
try {
pr.waitFor();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("test");
run = false;
}
});
// read(is);
new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
while (run)
try {
write(System.in, pr.getOutputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
while (run)
try {
write(pr.getInputStream(), System.out);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("finish");
}
}).start();
new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
while (run)
try {
write(pr.getErrorStream(), System.err);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
public static void write(InputStream is, OutputStream os)
throws IOException {
byte[] buf = new byte[1024];
int len = is.read(buf);
if (len != -1) {
byte[] data = new byte[len];
for (int i = 0; i < len; i++) {
data[i] = buf[i];
}
os.write(data);
os.flush();
}
}
}
What happens, is that I create a new Thread for every redirection of the streams, and the redirection itself happens via the write(inputStream,outputStream) method.
But the thread I use to check if the process is closed (pr.waitFor()) doesn't work as i thought it would. So I don't get noticed if the cmd is closed.
EDIT2
Ok I just forgot to start the Thread. But now I was able to get close to the problem.
The redirection of System.in to the process.getOutputStream() doesn't notice that the process is going to be closed. That's because is.read(buf) is a blocking method. So if I try to write a new command to the Process, then it notices that the streams should be closed and finishes the program.
If there is any solution for redirecting the Streams without threads, I'd like to implement it that way. I think this would be easier to use.
the main problem is you didn't do .start on the thread but i also want to suggest an improvement
wait for the process in the main thread:
public class Main {
public static boolean run = true;
public static void main(String[] args) throws IOException {
ProcessBuilder p = new ProcessBuilder("cmd");
final Process pr = p.start();
// read(is);
new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
while (run)
try {
write(System.in, pr.getOutputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
while (run)
try {
write(pr.getInputStream(), System.out);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("finish");
}
}).start();
new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
while (run)
try {
write(pr.getErrorStream(), System.err);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
try {
pr.waitFor();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("test");
run = false;
}
public static void write(InputStream is, OutputStream os)
throws IOException {
byte[] buf = new byte[1024];
int len = is.read(buf);
if (len != -1) {
byte[] data = new byte[len];
for (int i = 0; i < len; i++) {
data[i] = buf[i];
}
os.write(data);
os.flush();
}
}
}
I'm guessing that is because your main thread could exit before all those threads complete. Try adding pr.waitFor() right at the end of your main function.

Optimizing Java Socket Sending Android to PC

I need Your help!
So I got this app on an Android device, in which I get data from the accelerometer, and button presses which get this data to an edittext, and sets listeners on the edittextes.
When it's changed, there's a functions that creates a socket, sends data, and closes the socket.
Then I have a server app on my computer, in which I create serversockets, and create two threads that are waiting for serversocket.accept() that gets the data and put it into texbox. Simple as that.
I'm glad that I got it working anyway :-) but the point is, it's not working so well. I believe that whole communication is bad and not optimized. It sends data well, but often freezes, then unfreezes and sends quickly all previous data and so on.
I'm sorry for my bad code, but can someone please take a good look on this, and propose what I should change and how I could make it work more smooth and stable? :-(
Here's the Client code:
package com.test.klienttcp;
//import's...
public class Klient extends Activity implements SensorListener {
final String log = "Log";
EditText textOut;
EditText adres;
EditText test;
EditText gazuje;
TextView textIn;
TextView tekst;
TextView dziala;
String numer = null;
float wspk = 0; // wspolczynniki kalibracji
float wychylenietmp = 0;
float wychylenie = 0;
int tmp = 0;
int i = 0;
boolean wysylaj = false;
SensorManager sm = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
textOut = (EditText)findViewById(R.id.textout);
adres = (EditText)findViewById(R.id.adres);
gazuje = (EditText)findViewById(R.id.gazuje);
Button kalibracja = (Button)findViewById(R.id.kalibracja);
Button polacz = (Button)findViewById(R.id.polacz);
Button gaz = (Button)findViewById(R.id.gaz);
Button hamulec = (Button)findViewById(R.id.hamulec);
kalibracja.setOnClickListener(kalibracjaOnClickListener);
polacz.setOnClickListener(polaczOnClickListener);
gaz.setOnTouchListener(gazOnTouchListener);
hamulec.setOnTouchListener(hamulecOnTouchListener);
sm = (SensorManager) getSystemService(SENSOR_SERVICE);
//text listener steering
textOut.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
if(wysylaj)
{
Wyslij();
}
}
});
//text listener for throttle
gazuje.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
if(wysylaj)
{
Gaz();
}
}
});
}
Button.OnClickListener polaczOnClickListener
= new Button.OnClickListener(){
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
if(wysylaj==false)
{
wysylaj = true;
}
else
{
wysylaj = false;
}
}};
//throttle button handler
Button.OnTouchListener gazOnTouchListener
= new Button.OnTouchListener(){
#Override
public boolean onTouch(View arg0, MotionEvent event) {
// TODO Auto-generated method stub
if(event.getAction() == MotionEvent.ACTION_DOWN) {
gazuje.setText("1");
} else if (event.getAction() == MotionEvent.ACTION_UP) {
gazuje.setText("0");
}
return false;
}};
//brake button handler
Button.OnTouchListener hamulecOnTouchListener
= new Button.OnTouchListener(){
#Override
public boolean onTouch(View arg0, MotionEvent event) {
// TODO Auto-generated method stub
if(event.getAction() == MotionEvent.ACTION_DOWN) {
gazuje.setText("2");
} else if (event.getAction() == MotionEvent.ACTION_UP) {
gazuje.setText("0");
}
return false;
}};
//sensor handler
public void onSensorChanged(int sensor, float[] values) {
synchronized (this) {
if (sensor == SensorManager.SENSOR_ACCELEROMETER) {
wychylenie = values[0] * 10;
tmp = Math.round(wychylenie);
wychylenie = tmp / 10;
if(wychylenie != wychylenietmp)
{
textOut.setText(Float.toString(wychylenie - wspk));
wychylenietmp = wychylenie;
}
}
}
}
public void onAccuracyChanged(int sensor, int accuracy) {
Log.d(log, "onAccuracyChanged: " + sensor + ", accuracy: " + accuracy);
}
#Override
protected void onResume() {
super.onResume();
sm.registerListener(this, SensorManager.SENSOR_ORIENTATION
| SensorManager.SENSOR_ACCELEROMETER,
SensorManager.SENSOR_DELAY_NORMAL);
}
#Override
protected void onStop() {
sm.unregisterListener(this);
super.onStop();
}
//callibration handler
Button.OnClickListener kalibracjaOnClickListener
= new Button.OnClickListener(){
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
try {
wspk = wychylenie;
} catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}};
// sending steering data
public void Wyslij()
{
Socket socket = null;
DataOutputStream dataOutputStream = null;
DataInputStream dataInputStream = null;
try {
numer = adres.getText().toString();
socket = new Socket(numer, 8888);
dataOutputStream = new DataOutputStream(socket.getOutputStream());
dataInputStream = new DataInputStream(socket.getInputStream());
dataOutputStream.writeUTF(textOut.getText().toString());
if(socket.isClosed())
{
test.setText("Socket zamkniety");
}
//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();
}
}
}
}
//sending throttle data
public void Gaz()
{
Socket socket = null;
DataOutputStream dataOutputStream = null;
DataInputStream dataInputStream = null;
try {
numer = adres.getText().toString();
socket = new Socket(numer, 8889);
dataOutputStream = new DataOutputStream(socket.getOutputStream());
dataInputStream = new DataInputStream(socket.getInputStream());
dataOutputStream.writeUTF(gazuje.getText().toString());
if(socket.isClosed())
{
test.setText("Socket zamkniety");
}
//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();
}
}
}
}
}
And here's Server code:
//import's...
public class Okno
{
public static float wychylenie;
public static String gaz="0";
public static float jedzie;
public static int skrecam, gazuje;
public static String wiadomosc="100";
private static int maxConnections=0, port=8888, portg=8889;
public static void main(String[] args)
{
skrecam = 0;
gazuje = 0;
Window ok = new Window();
ok.setDefaultCloseOperation(3);
ok.setVisible(true);
ok.setResizable(false);
ok.setTitle("Serwer TCP");
int i=0;
try{
Robot robot = new Robot();
Robot robotgaz = new Robot();
ServerSocket listener = new ServerSocket(port);
ServerSocket listenergaz = new ServerSocket(portg);
while((i++ < maxConnections) || (maxConnections == 0)){
//create thread for steering
if(skrecam == 0)
{
skrecam=1;
doComms conn_c= new doComms(listener);
Thread t = new Thread(conn_c);
t.start();
}
//create thread for throttle
if(gazuje == 0)
{
gazuje=1;
doCommsgaz conn_gaz= new doCommsgaz(listenergaz);
Thread tgaz = new Thread(conn_gaz);
tgaz.start();
}
ok.pole3.setText(wiadomosc);
ok.pole2.setText(gaz);
}
}
catch (AWTException e) {
e.printStackTrace();
}
catch (IOException ioe) {
//System.out.println("IOException on socket listen: " + ioe);
ioe.printStackTrace();
}
}
}
class doComms implements Runnable {
private Socket server;
private ServerSocket listener;
private String line,input;
doComms(ServerSocket listener) {
this.listener=listener;
}
public void run () {
input="";
try {
Socket server;
server = listener.accept();
// Get input from the client
DataInputStream in = new DataInputStream (server.getInputStream());
//PrintStream out = new PrintStream(server.getOutputStream());
Okno.wiadomosc = in.readUTF();
server.close();
Okno.skrecam=0;
} catch (IOException ioe) {
//System.out.println("IOException on socket listen: " + ioe);
ioe.printStackTrace();
}
}
}
class doCommsgaz implements Runnable {
private Socket server;
private ServerSocket listener;
private String line,input;
doCommsgaz(ServerSocket listener) {
this.listener=listener;
}
public void run () {
input="";
try {
Socket server;
server = listener.accept();
// Get input from the client
DataInputStream in = new DataInputStream (server.getInputStream());
//PrintStream out = new PrintStream(server.getOutputStream());
Okno.gaz = in.readUTF();
server.close();
Okno.gazuje=0;
} catch (IOException ioe) {
//System.out.println("IOException on socket listen: " + ioe);
ioe.printStackTrace();
}
}
}
class Window extends JFrame {
private JButton ustaw;
public JTextField pole1;
public JTextField pole2;
public JTextField pole3;
Window()
{
setSize(300,200);
getContentPane().setLayout(new GridLayout(4,1));
JPanel panel1 = new JPanel();
panel1.setLayout(new FlowLayout(1));
getContentPane().add(panel1);
pole1 = new JTextField(15);
panel1.add(pole1);
JPanel panel2 = new JPanel();
panel2.setLayout(new FlowLayout(1));
getContentPane().add(panel2);
pole2 = new JTextField(15);
panel2.add(pole2);
JPanel panel3 = new JPanel();
panel3.setLayout(new FlowLayout(1));
getContentPane().add(panel3);
pole3 = new JTextField(15);
panel3.add(pole3);
JPanel panel4 = new JPanel();
panel4.setLayout(new FlowLayout(1));
getContentPane().add(panel4);
ustaw = new JButton("Ustaw");
panel4.add(ustaw);
//action button handler
ustaw.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent zdarz){
try{
}
catch(Exception wyjatek){}
pole1.setText("costam");
}
});
}
}
Once again, sorry for the non optimized, and hard-to-read code. But please, if someone knows what would be better, please respond.
Thanks a lot!
The client socket code should go into an AsyncTask. Google has a good into to it here. This will not speed anything up but it will stop your app from freezing. You can put in a "Processing" message while displaying a progress dialog to let the user know that something is happening.

Categories