delay and missing of data sending from server to client

I am sending an object with some data to from server to client through socket using thread in every second. Initially client receives these data every second but eventually around after 10 minutes data comes late for example it takes 3 to 5 seconds.Moreover surprisingly, some data are missing.

I would be grateful if someone please let me know the reason and how can I solve it.

Thanks.

[406 byte] By [ishraka] at [2007-11-26 17:11:21]
# 1
If this is client/server it must be TCP, and TCP does not lose data, so you must have a bug in your code.
ejpa at 2007-7-8 23:39:10 > top of Java-index,Core,Core APIs...
# 2
Yes, I think you have a bug. Do you collect all data received? Check how do you deal with all previously collected data then new packet comes.BTW are you sure server send data every second? May be after 10 minutes server starts to send data every 5 seconds? I have no idea why...
Michael.Nazarov@sun.coma at 2007-7-8 23:39:10 > top of Java-index,Core,Core APIs...
# 3
Post a code snippet.
duckbilla at 2007-7-8 23:39:10 > top of Java-index,Core,Core APIs...
# 4

Thanks to all.

As mentioned data shouldn't be lost I think it's because my computer is pentium 3 766 MHz,Ram 256MB. However, serious problem is although sleep time is 1000 from the server side client is receiving data initially fine but as the time goes by it's getting slower and slower.The main part of the program is sending a packet of data,timer, and newsas an object which will go into charts and chart will be updated accordingly. The program is like a trading game. If I press any button the GUI (for example BUY button) not all the time but soemtimes I got IO Exception while reading data in the client side.

The following is the server side program

-

//DataWorker.java

while (fKeepRunning){

// Read a request from the DataClient

String client_msg = readNetInputLine ();

if (client_msg == null ) break;

// Only print message if it changes. Avoids printing same

// message for each data set.

if ( !client_msg.equals (client_last_msg))

fDataServer.println ("Message from " + fUser + ": "

+ client_msg);

client_last_msg = client_msg;

int number_of_currency = fDataServer.num_cur();

String name_of_currency[] = fDataServer.name_cur();

int dataCount = fDataServer.dataSize;

System.out.println("data Size: " + fDataServer.dataSize);

// Could interpret the request and do something accordingly

// but here we will just send a set of data values.

// Send the number of data values.

try {

writeNetOutputInt (1);

/********send number of currency to be played************/

writeNetOutputInt (number_of_currency);

writeNetOutputInt (dataCount);

for (int i = 0;i < number_of_currency;i++){

writeNetOutputLine(name_of_currency[i]);

}

}

catch (IOException e) {

break;

}

for(int s=0;s < fDataServer.dataSize;s++)//dataSize = 3000

{

fDataServer.broadcastData();

try {

Thread.sleep (1000);

}

catch (InterruptedException e){

fDataServer.println("Problem Sending Data: "+e.getMessage());

}

}

//broadcast function in DataServer

public synchronized void broadcastData() {

for(int i=0; i < fWorkerList.size(); i++) {

DataWorker client= (DataWorker)fWorkerList.get(i);

double dataFromDatabase[] = new double[currency.currency_number * 3];

for (int j = 0; j < currency.currency_number * 3; j++){

dataFromDatabase[j] = currency.currency_Couple[j][dataIndex];

}

String timer = currency.timer[dataIndexTimer];//from database

String news = currency.news[dataIndexNews];//from database

Packet packet = new Packet();

packet.SetCurNum(currency.currency_number);

packet.setTime(timer);

packet.setNews(news);

packet.setData(dataFromDatabase);

try {

client.writeNetOutputObject (packet);

}

catch (Exception ex) {

clientDisconnected(client.fUser,client);

System.out.println(ex);

}

}

dataIndex++;

dataIndexTimer++;

dataIndexNews++;

}

//

void writeNetOutputObject (Packet p)

throws IOException {

toServer.writeObject (p);

toServer.flush();

} // writeNetOutputObject

The following is the client side program

while (fKeepRunning) {

// Ask the server to send data.

try {

writeNetOutputLine (" send data");

}

catch (IOException e){

break;

}

// First number sent from server is an integer that gives

// the number of data values to be sent.

try {

num_channels = readNetInputInt ();

num_currency = readNetInputInt();

this.dataSize = readNetInputInt ();

for (int i = 0; i < num_currency;i++){

name_of_currency[i] = readNetInputLine();

}

}

catch (IOException e) {

break;

}

fDataClient.initializeChart(num_currency,name_of_currency);

for(int datarow = 0;datarow < dataSize;datarow++){//dataSize = 3000

try {

Packet pack = readNetInputObject();

pack.cur_Num = num_currency;

fDataClient.setDataTimer(pack.time);

fDataClient.setDataNews(pack.news);

fDataClient.setDataDouble(pack.data);

}

catch (Exception e) {

fDataClient.println("IO Exception while reading data");

closeServer();

break;

}

}

if (fServer != null) closeServer ();

fDataClient.setDisconnected ();

} // run

Packet readNetInputObject () {

try {

Packet p = new Packet();

p = (Packet)inObject.readObject ();

return p;

}

catch (Exception e) {

System.out.println(e.getMessage());

closeServer();

return null;

}

}

Thanks again.

ishraka at 2007-7-8 23:39:10 > top of Java-index,Core,Core APIs...
# 5

> As mentioned data shouldn't be lost I think it's because my computer is pentium 3 766 MHz,Ram 256MB.

That wouldn't cause data loss in TCP.

catch (IOException e) {

break;

}

Don't ever do this. Always print out the exception message. Otherwise you haven't a hope in hell of knowing what's really going on.

>Thread.sleep (1000);

What's this for?

> Packet readNetInputObject () {

> try {

>Packet p = new Packet();

>p = (Packet)inObject.readObject ();

What's this for? You're creating a new Packet then throwing it away on the next line. Just a waste of time and space.

You can't really expect anybody to make any sense of incomplete code. Where are the definitions of the following methods?

writeNetOutputLine()

writeNetOutputInt()

readNetInputLine()

readNetInputInt()

Where are the definitions and initializations of the following variables?

toServer

inObject

ejpa at 2007-7-8 23:39:10 > top of Java-index,Core,Core APIs...
# 6

Sorry for the incomplete code.

Thread.sleep(1000)

I already mentioned the above sleep for the chart will feed data every 1 second.

DataServer.java

// "Java Tech"

// Code provided with book for educational purposes only.

// No warranty or guarantee implied.

// This code freely available. No copyright claimed.

// 2003

//

// Began from StartApp5

package testapplet1;

import java.net.*;

import javax.swing.*;

import java.awt.*;

import java.awt.event.*;

import java.io.*;

import java.util.*;

/**

* A Prototype Remote Data Monitoring System <br><br>

*

* DataServer provides simulated data to multiple instances of

* DataClient. A DataClient connects via a socket and

* executes a simple login procedue. The client then sends a request

* for data from the Server. DataServer responds by first sending an

* integer for the number of data values in the set and then sends

* that number of simulate integer data values. These might be a set

* of sensor values.

*

* DataServer runs standalone. It provides a simple GUI for starting

* the server, displaying the status of the communications with the

* clients, and stopping the server.

*

* This server is intended to allow clients to monitor an experiment.

* It could run at the same time that a separate data acquisition

* program is running.The DAQ program, for example, could be programmed

* to periodically update a file with data of interest. This server

* could then read this file and send the data to the client.

*

* An instance of the thread class DataWorker is assigned to each

* client socket. It monitors the socket for requests from the

* client and then obtains the data (here it just creates some dummy

* data with random number generators) and sends it to the client.

* The DataWorker includes methods to read and write strings and

* numerical data with streams to the client.<br><br>

*

* Multiple clients can connect simultaneously. The default max users

* value is set to 10.

*

**/

public class DataServer extends JFrame

implements ActionListener, Runnable

{

// GUI setup attributes

JMenuItem fMenuClose= null;

// Networking setup

// Use a Vector to keep track of the DataWorker list.

Vector fWorkerList = null;

dataCurrency currency;

// Connect to clients

ServerSocket fServerSocket = null;

int fDataServerPort = 2222;// Default port number

// Client counting and limit

static int fClientCounter__ = 0;

static int fMaxClients__= 10;

// Number of data values per set or "event"

// static int fNumDataVals__ = 6;

static int fNumDataVals__ = 1;

// Flag for the server socket loop.

boolean fKeepServing = true;

// dataCurrency currency = new dataCurrency();

double dataFromDatabase[];

int counter = 0;

static int dataIndex = 0;

static int dataIndexNews = 0;

static int dataIndexTimer = 0;

int dataSize;

JButton fStartButton;

JPanel button_panel;

JButton fChatButton;

JTextField fTextField;

JPanel panel;

JTextArea aTextArea = new JTextArea();

JPanel jPanel2 = new JPanel();

JScrollPane area_scroll_pane;

JTextArea jTextArea1 = new JTextArea();

JLabel jLabel1 = new JLabel();

JLabel jLabel2 = new JLabel();

JTextField jTextField1 = new JTextField();

JLabel jLabel3 = new JLabel();

JTextField jTextField2 = new JTextField();

JPanel jPanel1 = new JPanel();

GridLayout gridLayout1 = new GridLayout();

GridLayout gridLayout2 = new GridLayout();

/** Open frame for the user interface. **/

public static void main (String [] args) {

// Can pass frame title in command line arguments

String title="DataServer";

if (args.length != 0) title = args[0];

DataServer f = new DataServer (title);

f.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);

f.setVisible (true);

} // main

/**

* Pass a title to the frame via the constructor

* argument. Build the GUI.

**/

DataServer (String title) {

super (title);

currency = new dataCurrency();

currency.createEURUSDTimeSeries();

this.dataSize = currency.dataSize;

try {

jbInit();

}

catch(Exception e) {

e.printStackTrace();

}

fWorkerList = new Vector ();

} // ctor

public synchronized double[] currencyRate()

{

dataFromDatabase = new double[currency.currency_number * 3];

for (int i = 0; i < currency.currency_number * 3; i++){

dataFromDatabase[i] = currency.currency_Couple[i][dataIndex];

}

dataIndex++;

return dataFromDatabase;

}

public synchronized String news()

{

return currency.news[dataIndexNews++];

}

public synchronized String timer()

{

return currency.timer[dataIndexTimer++];

}

public synchronized int num_cur()

{

return currency.currency_number;

}

public synchronized String[] name_cur()

{

return currency.currency_Name;

}

/** Process events from the frame menu and the chooser. **/

public void actionPerformed (ActionEvent e) {

boolean status = false;

String command = e.getActionCommand ();

if(command.equals("Chat")){

new ChatServer(2000);

}else

if (command.equals ("Start") ) {

try {

fDataServerPort = Integer.parseInt (fTextField.getText ());

}

catch (NumberFormatException nfe){

println ("Bad port number");

return;

}

fStartButton.setEnabled (false);

Thread thread = new Thread (this);

thread.start ();

} else if (command.equals ("Quit") ){

fKeepServing = false;

dispose ();

}

} // actionPerformed

/** Create a ServerSocket and loop waiting for clients. **/

public void run () {

// The server_socket is used to make connections to

// DataClients at this port number

try {

fServerSocket = new ServerSocket (fDataServerPort);

}

catch (IOException e) {

println ("Error in server socket");

return;

}

println ("Waiting for users...");

// Loop here to grab clients

while (fKeepServing) {

try {

// accept () blocks until a connection is made

Socket socket = fServerSocket.accept ();

// Do the setup this socket and then loop

// back around to wait for the next DataClient.

DataWorker worker = new DataWorker (this, socket);

worker.start ();

}

catch (IOException ioe) {

println ("IOException: <" + ioe + ">");

break;

}

catch (Exception e) {

println ("Exception: <" + e + ">");

break;

}

}

} // run

/**

* When a DataWorker makes the connection, it checks to see if there

* is room on the server for it.

*

* We synchronize the method to avoid any problems with multiple clients

* interfering with each other.

**/

public synchronized boolean clientPermit () {

if (fWorkerList.size () < fMaxClients__)

return true;

else

return false;

}

/**

* A DataWorker will set up the connection with the client. If it

* decides that the conditions are OK, then it will invoke this

* method so that the parent server will add the worker to its list.

*

* We synchronize the method to avoid any problems with multiple

* clients interfering with each other.

**/

public synchronized void clientConnected (DataWorker worker) {

fWorkerList.add (worker);

System.out.println("No of client: " + fWorkerList.size() +"\n");

fClientCounter__++;

}

public synchronized void broadcastData(double [] data) {

for(int i=0; i < fWorkerList.size(); i++) {

DataWorker client= (DataWorker)fWorkerList.get(i);

try {

client.writeNetOutputDouble (data);

}

catch (IOException e) {

println("I/O: " +e.getMessage()+"\n");

break;

}

}

}

public synchronized void broadcastData() {

for(int i=0; i < fWorkerList.size(); i++) {

DataWorker client= (DataWorker)fWorkerList.get(i);

double dataFromDatabase[] = new double[currency.currency_number * 3];

for (int j = 0; j < currency.currency_number * 3; j++){

dataFromDatabase[j] = currency.currency_Couple[j][dataIndex];

}

String timer = currency.timer[dataIndexTimer];

String news = currency.news[dataIndexNews];

Packet packet = new Packet();

packet.SetCurNum(currency.currency_number);

packet.setTime(timer);

packet.setNews(news);

packet.setData(dataFromDatabase);

try {

client.writeNetOutputObject (packet);

}

catch (Exception ex) {

clientDisconnected(client.fUser,client);

System.out.println(ex);

}

}

dataIndex++;

dataIndexTimer++;

dataIndexNews++;

}

/**

* When a client disconnects, the DataWorker object will

* call back to this method to remove itself from the list

* of workers.

*

* We synchronize the method to avoid any problems with multiple clients

* interfering with each other.

**/

public synchronized void clientDisconnected (String user, DataWorker worker) {

println ("Client: "+user+" disconneced");

worker.fSocket = null;

fWorkerList.remove (worker);

fClientCounter__--;

}

/**

* This "helper method" makes a menu item and then

* registers this object as a listener to it.

**/

private JMenuItem makeMenuItem (String name){

JMenuItem m = new JMenuItem ( name );

m.addActionListener ( this );

return m;

}

/** Utility method to send messages to the text area. **/

public void println (String str){

//fTextArea.append (str +"\n");

jTextArea1.append (str +"\n");

repaint ();

}

public DataServer() {

try {

jbInit();

}

catch(Exception e) {

e.printStackTrace();

}

}

private void jbInit() throws Exception {

// Create a panel with a textfield and two buttons

JMenu m = new JMenu ("File");

// Use File menu to hold Quit command.

// fTextArea.setDoubleBuffered(false);

// fTextArea.setDisabledTextColor(Color.white);

fStartButton = new JButton ("Start");

button_panel = new JPanel ();

fChatButton = new JButton ("Chat");

fTextField = new JTextField ("2222");

panel = new JPanel (new GridLayout (1,2));

area_scroll_pane = new JScrollPane (aTextArea);

fStartButton.addActionListener(this);

fStartButton.setText("Start");

button_panel.setBorder(BorderFactory.createLineBorder(Color.black));

button_panel.setBounds(new Rectangle(3, 0, 169, 145));

button_panel.setLayout(gridLayout2);

fChatButton.addActionListener(this);

fChatButton.setToolTipText("");

fChatButton.setText("Chat");

panel.setLayout(null);

panel.setBackground(SystemColor.control);

panel.setBounds(new Rectangle(0, 2, 419, 145));

jPanel2.setLayout(null);

// area_scroll_pane.getViewport().setBackground(Color.gray);

area_scroll_pane.setBounds(new Rectangle(0, 0, 398, 256));

this.getContentPane().setLayout(null);

jPanel2.setBackground(Color.pink);

jPanel2.setBounds(new Rectangle(0, 145, 397, 255));

jTextArea1.setText("");

jLabel1.setBorder(BorderFactory.createLineBorder(Color.black));

jLabel1.setHorizontalAlignment(SwingConstants.CENTER);

jLabel1.setHorizontalTextPosition(SwingConstants.LEADING);

jLabel1.setText("Chat Port");

jLabel2.setBorder(BorderFactory.createLineBorder(Color.black));

jLabel2.setText("Server IP Address");

jTextField1.setBorder(BorderFactory.createLineBorder(Color.black));

jTextField1.setText("2000");

jLabel3.setBorder(BorderFactory.createLineBorder(Color.black));

jLabel3.setHorizontalAlignment(SwingConstants.CENTER);

jLabel3.setText("Game Port");

jTextField2.setBorder(BorderFactory.createLineBorder(Color.black));

jTextField2.setText("127.0.0.1");

jPanel1.setBackground(new Color(236, 234, 216));

jPanel1.setBorder(BorderFactory.createLineBorder(Color.black));

jPanel1.setBounds(new Rectangle(171, 0, 224, 145));

jPanel1.setLayout(gridLayout1);

gridLayout1.setColumns(2);

gridLayout1.setRows(4);

fTextField.setBorder(BorderFactory.createLineBorder(Color.black));

fTextField.setText("2222");

gridLayout2.setColumns(1);

gridLayout2.setRows(2);

button_panel.add(fStartButton, null);

button_panel.add(fChatButton, null);

panel.add(jPanel1, null);

jPanel1.add(jLabel1, null);

jPanel1.add(jTextField1, null);

jPanel1.add(jLabel3, null);

jPanel1.add(fTextField, null);

jPanel1.add(jLabel2, null);

jPanel1.add(jTextField2, null);

panel.add(button_panel);

this.getContentPane().add(jPanel2, null);

jPanel2.add(area_scroll_pane, null);

this.getContentPane().add(panel, null);

area_scroll_pane.getViewport().add(jTextArea1, null);

// content_pane.setLayout(new BorderLayout ());

this.setLocale(java.util.Locale.getDefault());

m.add (fMenuClose = makeMenuItem ("Quit"));

JMenuBar mb = new JMenuBar ();

mb.add (m);

setJMenuBar (mb);

setSize (new Dimension(396, 400));

show();

}

} // class DataServer

DataWorker.java

package testapplet1;

import java.io.*;

import java.net.*;

import java.util.*;

/**

* DataServer uses an instance of this class to service

* a DataClient connection. It waits for a data request

* and then obtains and sends the data.

*

* In actual use, the data could, for example be obtained from a

* taking diskfile updated by a DAQ system. Here, though, we simulate data

* by generating an array of random numberfDataServer.

**/

public class DataWorker extends Thread

{

// The parent server.

DataServer fDataServer;

// Name of the client

String fUser;

// Connection to the client.

Socket fSocket;

// I/O streams to the client

InputStream fNetInputStream;

OutputStream fNetOutputStream;

// Wrapped I/O streams

BufferedReaderfNetInputReader;

DataOutputStream fDataOutputStream;

ObjectOutputStream toServer = null;

PrintWriter fPrintWriter;

boolean fKeepRunning = true ;

double idat[] = new double[20];

// private ArrayList clientArray;

int dataIndex = 0;

Vector clientArray = null;

/**

* Pass reference to the owner DataServer and the

* index number for this DataSender instance.

**/

public DataWorker (DataServer s, Socket socket) {

fDataServer = s;

fSocket = socket;

// Random number generator need for dummy data creation.

clientArray = new Vector();

}

/** Send data to the client. **/

public void run () {

// If setup fails, end thread processing.

if ( !serviceSetup ()) return;

fDataServer.println (

"Client connection and login OK - Begin service...");

// Lower tpriority to give main parent and

// other threads some processor time.

setPriority (MIN_PRIORITY);

String client_last_msg = "";

// Begin the loop for communicating with the client.

while (fKeepRunning){

// Read a request from the DataClient

String client_msg = readNetInputLine ();

if (client_msg == null ) break;

// Only print message if it changes. Avoids printing same

// message for each data set.

if ( !client_msg.equals (client_last_msg))

fDataServer.println ("Message from " + fUser + ": "

+ client_msg);

client_last_msg = client_msg;

int number_of_currency = fDataServer.num_cur();

String name_of_currency[] = fDataServer.name_cur();

int dataCount = fDataServer.dataSize;

System.out.println("data Size: " + fDataServer.dataSize);

// Could interpret the request and do something accordingly

// but here we will just send a set of data values.

// Send the number of data values.

try {

// writeNetOutputInt (DataServer.fNumDataVals__);

writeNetOutputInt (1);

/********send number of currency to be played************/

writeNetOutputInt (number_of_currency);

writeNetOutputInt (dataCount);

for (int i = 0;i < number_of_currency;i++){

writeNetOutputLine(name_of_currency[i]);

}

}

catch (IOException e) {

break;

}

for(int s=0;s < fDataServer.dataSize;s++)

{

fDataServer.broadcastData();

try {

Thread.sleep (500);

}

catch (InterruptedException e){

fDataServer.println("Problem Sending Data: "+e.getMessage());

}

}

}

// Send message back to the text area in the frame.

fDataServer.println (fUser + " has disconnected.");

// Do any other tasks for ending the worker.

signOff ();

} // run

/**

* Set up the connection to the client. This requires obtaining the

* IO streams, carrying out the login prototcol, and then starting

* a DataWorker thread to tend to the client.

*

* The bookkeeping code is a bit messy because we check both reads

* and writes for errors in case the connection breaks down.

*

* The reads catch their own IOExceptions and return a null, while

* string writes use a PrintWriter that doesn't throw IOException. So

* we use the checkError () method and throw it ourselvefDataServer.

**/

public boolean serviceSetup () {

fDataServer.println ("Client setup...");

// First get the in/out streams from the socket to the client

try{

fNetInputStream = fSocket.getInputStream ();

fNetOutputStream = fSocket.getOutputStream ();

toServer = new ObjectOutputStream(fSocket.getOutputStream());

}

catch (IOException e){

fDataServer.println ("Unable to get input/output streams");

return false;

}

// Create a PrintWriter class for sending text to the client.

// The writeNetOutputLine method will use this class.

try{

fPrintWriter = new PrintWriter (

new OutputStreamWriter (fNetOutputStream, "8859_1"), true );

}

catch (Exception e) {

fDataServer.println ("Fails to open PrintWriter to client!");

return false;

}

// Check if the server has room for this client.

// If not, then send a message to this client to tell it the bad news.

if ( !fDataServer.clientPermit () ) {

try{

String msg= "Sorry, We've reached the maximum number of clients";

writeNetOutputLine (msg);

fDataServer.println (msg);

return false;

}

catch (IOException e){

fDataServer.println ("Connection fails during login");

return false;

}

}

// Get a DataInputStream wrapper so we can use its readLine () methods.

fNetInputReader =

new BufferedReader (new InputStreamReader (fNetInputStream));

// Do a simple login protocol. Send a request for the users name.

// Note a password check could be added here.

try{

writeNetOutputLine ( "Username: ");

}

catch (IOException e){

fDataServer.println ("Connection fails during login");

return false;

}

// Read the user name.cHECK USER NAME AND VALID HERE

fUser = readNetInputLine ();

if (fUser == null ) {

fDataServer.println ("Connection fails during login");

return false;

}

// Send a message that the login is OK.

try{

writeNetOutputLine ("Login successful");

fDataServer.println ("Login successful for " + fUser);

} catch (IOException e){

fDataServer.println ("Connection fails during login for " + fUser);

return false;

}

fDataServer.println (fUser + " connected! ");

fDataServer.println (fSocket.toString ());

// The login is successful so now create a DataWorker to

// service this client. Pass it an ID number

fDataServer.clientConnected (this);

// Get a data output stream for writing numerical data to the client

fDataOutputStream = new DataOutputStream (fNetOutputStream);

return true;

} // serviceSetup

/** Whenever this client disconnects tell the parent. **/

public void signOff () {

try{

fSocket.close ();

}catch (Exception e){

fDataServer.println ("Socket close exception for " + fUser);

}

fDataServer.clientDisconnected (fUser,this);

} // signOff

/** Utility method to read a whole text line.**/

String readNetInputLine () {

try {

return fNetInputReader.readLine ();

}

catch (IOException e){

return null;

}

} // readNetInputLine

/**

* Output is wrapped with a PrintWriter, which doesn't throw

* IOException. So we invoke the checkError() method and then

* throw an exception if it detects an error.

**/

void writeNetOutputLine (String string)

throws IOException {

System.out.println(string);

fPrintWriter.println (string);

if ( fPrintWriter.checkError ()) throw (new IOException ());

fPrintWriter.flush ();

if ( fPrintWriter.checkError ()) throw (new IOException ());

} // writeNetOutputLine

void writeNetOutputObject (Packet p)

throws IOException {

toServer.writeObject (p);

toServer.flush();

} // writeNetOutputObject

/** Utility to write integer values to the output stream. **/

public void writeNetOutputInt (int i)

throws IOException {

fDataOutputStream.writeInt (i);

fDataOutputStream.flush ();

} // writeNetOutputInt

/** Utility to write float values to the output stream.**/

public void writeNetOutputFloat (float f)

throws IOException {

fDataOutputStream.writeFloat (f);

fDataOutputStream.flush ();

} // writeNetOutputFloat

void writeNetOutputDouble (double[] d)

throws IOException {

for (int i=0;i < d.length;i++){

fDataOutputStream.writeDouble(d[i]);

fDataOutputStream.flush();

}

} // writeNetOutputFloat

} // class DataWorker

DataClientWorker.java

// "Java Tech"

// Code provided with book for educational purposes only.

// No warranty or guarantee implied.

// This code freely available. No copyright claimed.

// 2003

//

package testapplet1;

import java.io.*;

import java.net.*;

import java.awt.event.*;

/**

* DataClient creates an instance of this thread class to tend to the connection

* to the data server.

*

* It periodically requests a set of data from the server and then sends the

* data to the parent DataClient, which will update its display.<br><br>

**/

public class DataClientWorker extends Thread

{

// Flag for data running.

boolean fKeepRunning = true;

Chat fDataClient;

// Networking refs

Socket fServer;

String fUserName ;

// I/O with the server

BufferedReader fNetInputReader ;

DataInputStream fNetInputDataStream;

OutputStreamfNetOutputDataStream;

PrintWriterfPrintWriter ;

private ObjectInputStream inObject;

double dataFromServer[] = new double[12];

int dataSize = 1;

// Data array

int [] fData = null;

/** Receive the DataClient to provide with the data from the server. **/

public DataClientWorker (Chat c, Socket server, String userName) {

fDataClient = c;

fServer= server;

fUserName= userName;

}

/** Remain in a loop to monitor the I/O from the server. Display the data.**/

public void run () {

// The socket connection was made by the caller, now

// set up the streams and do a login

try {

if (!doConnection ()){

fDataClient.println (" Connection/login failed");

return;

}

}

catch (IOException ioe) {

fDataClient.println (" I/O exception with serve:"+ ioe);

}

int num_currency = 4;

String name_of_currency[] = new String[4];

// This loops until either the connection is broken or the

//stop button or stop key is hit

while (fKeepRunning) {

// Ask the server to send data.

try {

writeNetOutputLine (" send data");

}

catch (IOException e){

break;

}

// First number sent from server is an integer that gives

// the number of data values to be sent.

try {

num_channels = readNetInputInt ();

num_currency = readNetInputInt();

this.dataSize = readNetInputInt ();

for (int i = 0; i < num_currency;i++){

name_of_currency[i] = readNetInputLine();

}

System.out.println(num_currency + num_currency);

}

catch (IOException e) {

break;

}

fDataClient.initializeChart(num_currency,name_of_currency);

if (num_channels != fNumChannels) {

fNumChannels = num_channels;

//fDataClient.println (" Number data channels = " + fNumChannels);

}

if (fNumChannels < 1){

fDataClient.println (" no data");

break;

}

// Create an array to hold the data if not available

if (fData == null || fNumChannels != fData.length)

fData = new int[fNumChannels];

for(int datarow = 0;datarow < dataSize;datarow++){

try {

Packet pack = readNetInputObject();

pack.cur_Num = num_currency;

fDataClient.setDataTimer(pack.time);

fDataClient.setDataNews(pack.news);

fDataClient.setDataDouble(pack.data);

}

catch (Exception e) {

fDataClient.println("IO Exception while reading data");

closeServer();

break;

}

}

if (fServer != null) closeServer ();

// fDataClient.println ("disconnected");

fDataClient.setDisconnected ();

} // run

/** Set up the streams with the server and then login. **/

boolean doConnection () throws IOException {

// Get the input and output streams from the socket

InputStream in = fServer.getInputStream ();

// Use the reader for obtaining text

fNetInputReader = new BufferedReader (

new InputStreamReader (in)) ;

// User the DataInputStream for getting numerical values.

fNetInputDataStream = new DataInputStream ( in );

// Output stream for sending messages to the server.

fNetOutputDataStream = fServer.getOutputStream ();

// Write with a PrintWriter for sending text to the server.

fPrintWriter= new PrintWriter (

new OutputStreamWriter (fNetOutputDataStream, "8859_1"), true );

try {

inObject = new ObjectInputStream(fServer.getInputStream());

}

catch(IOException ex) {

System.out.println(ex.getMessage());

}

// Now try the login procedure.

if (!login ()) return false;

return true;

} // doConnection

/** Here is a homemade login protocol. A password could easily

* be added.

**/

boolean login () {

// fDataClient.println ("Waiting for login prompt...");

String msg_line=readNetInputLine ();

if (msg_line == null) return false;

// fDataClient.println (msg_line);

if (!msg_line.startsWith ("Username:")) return false;

// fDataClient.println ("Send username " + fUserName);

try {

writeNetOutputLine (fUserName);

}

catch (IOException e) {

return false;

}

catch (Exception e) {

fDataClient.println ("Error occurred in sending username!");

return false;

}

fDataClient.println ("Waiting for response...");

msg_line=readNetInputLine ();

if (msg_line == null) return false;

fDataClient.println (msg_line);

return true;

} // login

/** Do all of the steps needed to stop the connection. **/

public void finish (){

// Kill the thread and stop the server

fKeepRunning = false;

closeServer ();

}

/** Close the socket to the server. **/

void closeServer () {

if (fServer == null) return;

try {

fServer.close ();

fServer = null;

}

catch (IOException e)

{}

}

/**

* The net input stream is wrappped in a DataInputStream

* so we can use readLine, readInt and readFloat

**/

Packet readNetInputObject () {

try {

Packet p = new Packet();

p = (Packet)inObject.readObject ();

return p;

}

catch (Exception e) {

System.out.println(e.getMessage());

closeServer();

return null;

}

}

String readNetInputLine () {

try {

return fNetInputReader.readLine ();

}

catch (IOException e) {

return null;

}

}

/** Read an integer value from the socket stream **/

int readNetInputInt () throws IOException {

return fNetInputDataStream.readInt ();

}

double readNetInputDouble () throws IOException {

return fNetInputDataStream.readDouble ();

}

/** Read float value from the socket stream. **/

float readNetInputFloat () throws IOException {

return fNetInputDataStream.readFloat ();

}

/**

* The net output is a PrintWriter class which doesn't throw

* IOException itself. Instead we have to use the PrintWriter

* checkError () method and throw an exception ourselves if there

* was an output error.

**/

void writeNetOutputLine (String string) throws IOException {

fPrintWriter.println (string);

if (fPrintWriter.checkError ()) throw (new IOException ());

fPrintWriter.flush ();

if (fPrintWriter.checkError ()) throw (new IOException ());

} // writeNetOutputLine

} // class DataClientWorker

fDataClient.setDataDouble(pack.data);

The data in the above line is read by the chart. Server takes around 45 minutes to send all these data at one second interval.During this time, user will buy or sell. But when pressing buy or sell button there are too many IO exception right now. Is it because I am interrupting data transfer! Is there anyway to get rid of this problem.

Sorry for lot of questions. I am almost new to Java but implementing a heavy project.!

Thanks again.

ishraka at 2007-7-8 23:39:10 > top of Java-index,Core,Core APIs...
# 7

Please see this line

Packet pack = readNetInputObject();

When I open second instance of my client program It's giving me illegal handle value at the above line.

I have no idea about that error. In fact a few days ago opening several client did work fine.

Thanks for your help.

ishraka at 2007-7-8 23:39:10 > top of Java-index,Core,Core APIs...
# 8

You're building several different kinds of streams on top of the socket's input and output streams, and at least two of them do buffering: the BufferedReader and the ObjectInputStream. This is why you're losing data: the OIS is looking for data that's already been read into the BR's buffer and vice versa.

You can't do this, it will never work. Rethink using a single stream for input and another for output.

ejpa at 2007-7-8 23:39:10 > top of Java-index,Core,Core APIs...
# 9

Hello all,

I have almost overcome most of the problems except sometimes IOException occurs if I press any button on the GUI. As It's already described Server is continuously sending and Clients are continuously receiving same data when the program is running. But sometimes when I press any button it gives the above mentioned error and socket closed.

In my mind, since client is receiving datas continuously button press is causing the interruption. But it doesn't happen all the time.

I would be ever grateful if someone helps me in this regard. I have just this week to deliver the project.

Thanks.

ishraka at 2007-7-8 23:39:10 > top of Java-index,Core,Core APIs...
# 10
IOException with what text message? and thrown by what method?
ejpa at 2007-7-8 23:39:10 > top of Java-index,Core,Core APIs...
# 11

> when I press any button

There are only two buttons. One is disabled after its first use so it should not be a problem because your socket io is running in a thread separate from GUI thread . Another button is not disabled and does, potentially multiple times, instantiate a ChatServer object of which code is unknow to us. The culprit(s) should be the button and/or the ChatServer code.

hiwaa at 2007-7-8 23:39:10 > top of Java-index,Core,Core APIs...