我有一個Java編程的Socket-Client程序。我正在使用DataOutputStream將消息發送到服務器套接字。有時DataOutputstream上的writed消息沒有發送到ServerSocket。我認爲這是因爲我在發送消息後沒有臉紅。我這樣做,但沒用。如果我終止類的執行,那麼只有我從ServerSocket接收消息。使用DataOutputStream向服務器套接字寫入消息到客戶端套接字只在關閉客戶端套接字後發送爲什麼?
我的代碼:
public class LoggingClient {
LinkedBlockingQueue<byte[]> messages = new LinkedBlockingQueue<byte[]>();
public static LoggingClient clientObj;
/*
* waiting 2 seconds for connecting centralized log server . If it's not reachable writing log's in local machine
* this log's will be collected on eclipse restart.
*/
public static final int SOCKET_TIMEOUT = 2000;
/**
* Server which the log server is currently running.
*/
public static final String SERVER = "bharathi";
/**
* Port which the log server is running.
*/
public static final int PORT = 10000;
/**
* Client socket used to connect the server .
*/
Socket client = null;
public static Logger logger = Logger.getLogger(LoggingClient.class.getName());
/**
* Used to write given logs into client output stream.
*/
DataOutputStream out = null;
public boolean isConnected = false;
/**
* Used for preventing instaniate LoggingClient without calling getInstance method.
*/
private LoggingClient(){
}
/**
* Clear's the socket and initialize new socket .
*/
public void init(){
try{
clear();
client = new Socket();
client.setTcpNoDelay(true);
client.connect(new InetSocketAddress(SERVER,PORT),SOCKET_TIMEOUT); //trying to make connection within two seconds.
out = new DataOutputStream(client.getOutputStream());
isConnected = true;
}catch(Exception e){
isConnected = false;
}
}
public static LoggingClient getInstance(){
if(clientObj == null){
clientObj = new LoggingClient();
}
return clientObj;
}
public void clear(){
try{
if(out != null){
out.close(); //if we call close method it invokes flush and then closes the DataOutputStream.
}
if(client != null){
client.close();
}
}catch(Exception e){
logger.log(Level.INFO,"Error while closing connection , reason {0}",e);
}finally{
try{
client.close();
out.close();
}catch(Exception e){
}
isConnected = false;
}
}
/**
* Adding this message into a queue . Scheduled thread will get this logs and push into central logging server.
* @param message
*/
public synchronized void write(byte[] message){
if(!isConnected){ //has connection.
init();
}
messages.add(message); //adding message to this queue . Background thread will collect the log message and sent it to the central log server.
}
/**
* Sending logs into central log server . If it's not reachable write into local machine.
* @param message
*/
public void sendLog(byte[] message){
try {
out.write(message);
out.flush();
} catch (Exception e) {
writeInLocalMachine(localLoggingPath, message); //in case of failure writing logs in local machine . Sync this logs when restart of eclipse.
}
}
/**
* Writing log's into his machine this log will be synced on plugin startup.
* @param file - File path.
* @param message - Message to log.
*/
public static void writeInLocalMachine(String file, byte[] message) {
FileOutputStream fileWriter = null;
File f = new File(file);
try {
if(!f.exists()){
f.createNewFile();
}
fileWriter = new FileOutputStream(file, true);
fileWriter.write(message);
fileWriter.flush();
} catch (Exception e) {
logger.log(
Level.WARNING,
"This may be due to given file not found in system , reason {0}",
e);
} finally {
try{
fileWriter.close();
}catch(Exception e){
}
}
}
/**
* @return - Recently received message from queue . Returns null if it's empty.
*/
public byte[] getMessage(){
return messages.poll(); //returns the head element and deletes it.
}
}將消息發送到服務器套接字
測試Java類。
public class LogTest implements Runnable {
public static final String LINE_SEPARATOR = System.getProperty("line.separator");
@Override
public void run() {
while(true){
try{
LoggingClient client = LoggingClient.getInstance();
byte[] message = client.getMessage();
if(message != null){
client.sendLog(message);
}
}catch(Exception e){
}
}
}
public static void startSending(){
for(int i=0;i<10000;i++){
String msg = "msg number" + i+LINE_SEPARATOR;
LoggingClient.getInstance().write(msg.getBytes());
}
}
public static void main(String args[]){
LoggingClient c = LoggingClient.getInstance();
System.out.println("START TIME " + System.currentTimeMillis());
Thread t = new Thread(new LogTest(),"LOG MESSAGER");
t.start();
startSending();
System.out.println("END TIME " + System.currentTimeMillis());
}
發送的消息將被存儲在一個文件中。
輸出繼電器:
START TIME 1340815857896
END TIME 1340815858063
成品將消息到隊列中。無限while循環將負責將日誌發送到服務器套接字。
存儲在文件中的內容是0字節爲什麼? 。如果我停止跑班,我收到發送的消息爲什麼?
你的問題是相當徒勞的,直到你寫一些代碼來顯示所有的異常,並告訴我們哪一個被拋出。目前它可能是任何東西。 – EJP
@EJP它不會拋出異常。 – kannanrbk
用那個代碼你怎麼可能告訴? – EJP