服务器代码部分内容如下:
Message是一个类,类里面有private int IDFrom;
private int IDTo;
private int type;
private Object Content;
type是判断我服务器收到的内容是一个命令还是消息,命令有登陆,传文件等。
首先,我们收到一个Message,它让一个客户登陆了。
接着发送了一个消息,消息到达了服务器,放在了服务器的一个临界区里,是linkedlist型的。
另一个客户也登陆了,要接收这个消息。
于是就接收不到了。
经过反复研究,发现它是卡在了if((objMsg = ins.readObject())!= null )。
要有第二条消息发送过来,它才能接收前一条。
这样消息就不仅仅是延迟了。
请问该怎么解决这个问题。。
抱拳感谢!!!package try1;
import java.io.*;import java.net.*;
import java.io.*;
import java.util.*;public class Server implements Serializable{
public static void main(String[] args) throws IOException
{
Thread thread = new Thread()
{
private ServerSocket server;
private int threadID = 0;
public void run()
{
try
{
System.out.println("================服务器已启动================");
server = new ServerSocket(8888);
while(true)
{
Socket client = server.accept();
//输出提示
System.out.println("有新的连接......"+client.getInetAddress());
threadID ++;
ServerThread clientthread = new ServerThread(client,threadID);
clientthread.start();
}
}
catch(IOException ex)
{
}
}
};
thread.start();
}
}class ServerThread extends Thread{
private Socket netClient;
private int threadID;
private static LinkedList[] msgList = new LinkedList[100];
private static HashMap<Integer ,Integer> threadMap = new HashMap<Integer,Integer>();
public ServerThread(Socket client,int threadID) throws IOException
{
this.netClient = client;
this.threadID = threadID;
msgList[threadID] = new LinkedList();
}
//--------------------------------------
//读取各线程接收的消息列表
//--------------------------------------
public synchronized Object ReadMsg(int threadid)
{
return(msgList[threadid].remove());
}
public synchronized boolean WriteMsg(int threadid,Object msg)
{
return(msgList[threadid].add(msg));
}
//---------------------------------------
//读取当前线程获得消息的来源
//---------------------------------------
public synchronized int ReadThreadID(int userid)
{
//return threadMap.get(userid);
if(threadMap.containsKey(userid))
return threadMap.get(userid);
else
return 0;
}
public synchronized void WriteUserID(int userid,int threadid)
{
threadMap.put(userid,threadid);
}
public void run()
{
//输出提示
System.out.println(netClient.getInetAddress()+"客户服务线程"+threadID+"已启动...");
try
{
ObjectOutputStream outs = new ObjectOutputStream(netClient.getOutputStream());
ObjectInputStream ins = new ObjectInputStream(netClient.getInputStream());
Object objMsg;
while(true)
{
if((objMsg = ins.readObject())!= null )//!!!!!!!!!!!!!卡在了里!!!!!
{
Message msg = (Message)objMsg;
System.out.println("命令类型:"+msg.getType());
switch(msg.getType())
{
case 1://表示用户发送消息命令
int threadid = ReadThreadID(msg.getIDTo());
if(threadid != 0)//当线程ID=0时表示该信息是发送给服务器的
WriteMsg(threadid,objMsg);
break;
case 3://表示用户登录时注册命令
//提示信息
System.out.println("注册用户:"+msg.getIDFrom());
WriteUserID(msg.getIDFrom(),threadID);
System.out.println("该用户的线程号:" +ReadThreadID(msg.getIDFrom()));
//-----------------------------------
//其余登陆需要的操作
//-----------------------------------
break;
case 7:
break;
}
}
if( !msgList[threadID].isEmpty())
{
outs.writeObject(ReadMsg(threadID));
}
}
}
catch(IOException ex)
{
} catch (ClassNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Message是一个类,类里面有private int IDFrom;
private int IDTo;
private int type;
private Object Content;
type是判断我服务器收到的内容是一个命令还是消息,命令有登陆,传文件等。
首先,我们收到一个Message,它让一个客户登陆了。
接着发送了一个消息,消息到达了服务器,放在了服务器的一个临界区里,是linkedlist型的。
另一个客户也登陆了,要接收这个消息。
于是就接收不到了。
经过反复研究,发现它是卡在了if((objMsg = ins.readObject())!= null )。
要有第二条消息发送过来,它才能接收前一条。
这样消息就不仅仅是延迟了。
请问该怎么解决这个问题。。
抱拳感谢!!!package try1;
import java.io.*;import java.net.*;
import java.io.*;
import java.util.*;public class Server implements Serializable{
public static void main(String[] args) throws IOException
{
Thread thread = new Thread()
{
private ServerSocket server;
private int threadID = 0;
public void run()
{
try
{
System.out.println("================服务器已启动================");
server = new ServerSocket(8888);
while(true)
{
Socket client = server.accept();
//输出提示
System.out.println("有新的连接......"+client.getInetAddress());
threadID ++;
ServerThread clientthread = new ServerThread(client,threadID);
clientthread.start();
}
}
catch(IOException ex)
{
}
}
};
thread.start();
}
}class ServerThread extends Thread{
private Socket netClient;
private int threadID;
private static LinkedList[] msgList = new LinkedList[100];
private static HashMap<Integer ,Integer> threadMap = new HashMap<Integer,Integer>();
public ServerThread(Socket client,int threadID) throws IOException
{
this.netClient = client;
this.threadID = threadID;
msgList[threadID] = new LinkedList();
}
//--------------------------------------
//读取各线程接收的消息列表
//--------------------------------------
public synchronized Object ReadMsg(int threadid)
{
return(msgList[threadid].remove());
}
public synchronized boolean WriteMsg(int threadid,Object msg)
{
return(msgList[threadid].add(msg));
}
//---------------------------------------
//读取当前线程获得消息的来源
//---------------------------------------
public synchronized int ReadThreadID(int userid)
{
//return threadMap.get(userid);
if(threadMap.containsKey(userid))
return threadMap.get(userid);
else
return 0;
}
public synchronized void WriteUserID(int userid,int threadid)
{
threadMap.put(userid,threadid);
}
public void run()
{
//输出提示
System.out.println(netClient.getInetAddress()+"客户服务线程"+threadID+"已启动...");
try
{
ObjectOutputStream outs = new ObjectOutputStream(netClient.getOutputStream());
ObjectInputStream ins = new ObjectInputStream(netClient.getInputStream());
Object objMsg;
while(true)
{
if((objMsg = ins.readObject())!= null )//!!!!!!!!!!!!!卡在了里!!!!!
{
Message msg = (Message)objMsg;
System.out.println("命令类型:"+msg.getType());
switch(msg.getType())
{
case 1://表示用户发送消息命令
int threadid = ReadThreadID(msg.getIDTo());
if(threadid != 0)//当线程ID=0时表示该信息是发送给服务器的
WriteMsg(threadid,objMsg);
break;
case 3://表示用户登录时注册命令
//提示信息
System.out.println("注册用户:"+msg.getIDFrom());
WriteUserID(msg.getIDFrom(),threadID);
System.out.println("该用户的线程号:" +ReadThreadID(msg.getIDFrom()));
//-----------------------------------
//其余登陆需要的操作
//-----------------------------------
break;
case 7:
break;
}
}
if( !msgList[threadID].isEmpty())
{
outs.writeObject(ReadMsg(threadID));
}
}
}
catch(IOException ex)
{
} catch (ClassNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
楼主不妨将下面的那个if( !msgList[threadID].isEmpty())改成while( !msgList[threadID].isEmpty()),会好一些。
是这样,我们要接受的消息存放在了临界区,当外界没有继续给我们东西的时候,我们的INPUT是空的,于是程序卡在了readObject()等待下一条消息的来临。可是我们现在要从临界区里拿之前存放在里边属于我们的东西了,就拿不到了。那么该怎么办。
要么在read前拿临界区的东西。
要么多线程,read归read一个线程,拿归拿一个线程,互不影响。