好的,所以我一直在收到一些讓我的代碼工作的問題,所以我做了一個簡化版本的程序來弄清楚發生了什麼,但我仍然感到困惑。多線程程序中意外的I/O中斷
這裏的程序:
這是服務器代碼:
public class Server{
private ServerSocket server;
private Socket connection;
private DatagramSocket server_socket;
String compString = "";
public static List<String> messages = Collections.synchronizedList(new ArrayList<String>());
public static List<DatagramPacket> packets = Collections.synchronizedList(new ArrayList<DatagramPacket>());
public Server()
{
}
public void startRunning()
{
try
{
server_socket = new DatagramSocket(9876);
receiveAndSend();
}catch(Exception e)
{
System.out.println("Exception caught");
}
}
public void receiveAndSend()
{
Thread thread1 = new Thread()
{
public void run()
{
try{
while(true)
{
byte[] buffer = new byte[3000];
DatagramPacket request = new DatagramPacket(buffer, buffer.length);
server_socket.receive(request);
String mess = new String(request.getData());
synchronized(messages)
{
if(!messages.contains(mess) && !packets.contains(request))
{
addMessage(mess);
addPacket(request);
System.out.println("added: " + mess);
}
}
}
}catch(Exception e)
{
System.out.println("Exception caught");
}
}
};
thread1.start();
Thread thread2 = new Thread()
{
public void run()
{
try
{
while(true)
{
Thread.sleep(6000);
System.out.println("the list contains");
synchronized(messages)
{
compString = "";
for (String st : messages)
{
System.out.println(st);
}
System.out.println("!!!!!!!!!!!!!!!!!!");
if(!messages.isEmpty())
{
System.out.println(messages.size());
for(int i=0; i< messages.size(); i++)
{
compString += messages.get(i);
compString += "-";
}
}
}
System.out.println("final string is:" + compString + "\n");
for(DatagramPacket pack: packets)
{
try
{
InetAddress add = pack.getAddress();
int port = pack.getPort();
byte[] tbuffer = compString.getBytes();
DatagramPacket reply = new DatagramPacket(tbuffer, tbuffer.length, add, port);
server_socket.send(reply);
}catch(Exception e)
{
System.out.println("Exception caught");
}
}
}
}catch(Exception e)
{
}
}
};
thread2.start();
}
public synchronized void addMessage(String mess)
{
messages.add(mess);
}
public synchronized void addPacket(DatagramPacket packet)
{
packets.add(packet);
}
}
這是客戶端代碼:
public class Client {
public String message;
public int port;
public int server = 9876;
public void Client(String message)
{
this.message = message;
}
public void startRunning()
{
serverStart();
}
public void serverStart()
{
Thread thread1 = new Thread()
{
public void run()
{
try{
DatagramSocket ssocket = new DatagramSocket(port);
while(true)
{
Thread.sleep(5000);
byte [] m =message.getBytes();
InetAddress hhost = InetAddress.getByName("127.0.0.1"); //won't be always localh
DatagramPacket request = new DatagramPacket(m, m.length, hhost, server);
ssocket.send(request);
System.out.println("sending: " + message + "\n");
byte[] buffer = new byte[2000];
DatagramPacket reply = new DatagramPacket(buffer, buffer.length);
ssocket.receive(reply);
String receivedString = new String(reply.getData());
System.out.println("receivedString : " + receivedString);
if(receivedString != null && !receivedString.isEmpty())
{
}
}
}catch(Exception e)
{
System.out.println("Exception caught");
}
}
};
thread1.start();
}
public String[] convertStringToArray(String tstring)
{
tstring.trim();
String[] sarray = tstring.split("-");
return sarray;
}
}
您需要這3個運行代碼:
public class ServerTest {
public static void main(String[] args)
{
Server s = new Server();
s.startRunning();
}
}
public class ClientTest2 {
public static void main(String[] args)
{
Client myclient = new Client();
myclient.message = "Hello";
myclient.port = 6965;
myclient.startRunning();
}
}
public class ClientTest {
public static void main(String[] args)
{
Client myclient = new Client();
myclient.message = "Kitty";
myclient.port = 6646;
myclient.startRunning();
}
}
我得到下面的輸出,當我運行:
added: Helloadded: Kittythe list contains
Hello2
final string is:Hellothe list contains
Hello
!!!!!!!!!!!!!!!!!!
2
final string is:Hello
the list contains
Hello
!!!!!!!!!!!!!!!!!!
的問題是:1)中的println有時會被中斷,從不在上面的輸出中,我們可以看到該行!!!! !!!!!!!!!!有時候不會打印出來。 2)Arraylist中的某些元素不會被添加或不會被打印。
我確實試圖在每個地方放置同步的塊,但它似乎並沒有工作,其他各種事情也沒有幫助。
(脫離主題,但與獲得更好的幫助有關):一個空行足夠空白 - 爲了獲得更好的幫助,請將代碼格式化得很好,以便我們可以讀取它。 – 2015-04-02 04:10:02
'catch(Exception e) { }'是問題所在。想想看... – Holger 2015-04-02 16:46:20
不,不是。我刪除了catch塊內的打印語句,因爲我想查看這種行爲是否會以某種方式改變。前一段時間我添加了這些語句,輸出完全沒有改變。 – jarvan 2015-04-02 18:38:27