Java 我的套接字连接是否丢失了一些通过它发送的数据?

Java 我的套接字连接是否丢失了一些通过它发送的数据?,java,sockets,gson,locking,race-condition,Java,Sockets,Gson,Locking,Race Condition,我正在编写一个Connection类,它通过Commands和CommandResults双向发送和接收数据。但是,当通过连接快速发送多个请求时,有些请求无法正常通过 这听起来像是某种比赛条件,但我觉得我已经为此做好了准备: 锁定和解锁对套接字的写入 有一个已发送的命令s的表,其命令结果s尚未收到 以及锁定和解锁对所述桌子的改变 命令在单个线程上接收和处理,因此这不应该是问题所在 我已经看过代码很多次了,我觉得问题应该出在其他地方,但我的团队非常自信,连接是罪魁祸首 这个示例有点长,但我觉得

我正在编写一个
Connection
类,它通过
Command
s和
CommandResult
s双向发送和接收数据。但是,当通过
连接快速发送多个请求时,有些请求无法正常通过

这听起来像是某种比赛条件,但我觉得我已经为此做好了准备:

  • 锁定和解锁对套接字的写入
  • 有一个已发送的
    命令
    s的表,其
    命令结果
    s尚未收到
  • 以及锁定和解锁对所述桌子的改变
命令
在单个线程上接收和处理,因此这不应该是问题所在

我已经看过代码很多次了,我觉得问题应该出在其他地方,但我的团队非常自信,
连接
是罪魁祸首

这个示例有点长,但我觉得它很小,我可以制作一个完整的示例。不过,我确实确保它有很好的文档记录。需要了解的重要事项是:

  • s
    s只是一个未来。获取资源将被阻止,直到它被实际填充
  • 消息
    s只需包装请求和响应
  • 序列化程序基本上是一个gson包装器
  • Command
    s和
    CommandResult
    s使用公共UUID进行跟踪
  • ICommandHandler
    s接收
    命令
    并输出
    CommandResult
    Command
    s和
    CommandResult
    s的内容对此不重要
Connection.java:

公共类连接{
专用插座;
私有ICommandHandler;
专用序列化程序;
私有锁resultsLock;
私有锁socketWriteLock;
私人地图预订;
公共连接(插座){
ser=新序列化程序();
保留=新树映射();
handler=null;
this.socket=socket;
//设锁
resultsLock=new ReentrantLock();
socketWriteLock=新的ReentrantLock();
}
公共连接(字符串主机,int端口)抛出UnknownHostException,IOException{
套接字=新套接字(主机、端口);
ser=新序列化程序();
保留=新树映射();
handler=null;
//设锁
resultsLock=newreentrantlock(true);
socketWriteLock=新的可重入锁(true);
}
/*在套接字上发送命令,并等待响应
*
*@param com要发送的命令
*@返回命令操作的结果。
*/
公共命令结果发送命令(命令com){
试一试{
waitingwrapper delayedResult=reserversult(com);
编写(新消息(com));
CommandResult res=delayedResult.waitOnResource();
删除保存(com);
返回res;
}捕获(IOE异常){
e、 printStackTrace();
返回null;
}
}
/*设置传入命令的处理程序。还开始侦听套接字
*
*@param handler传入命令的处理程序
*/
public void setCommandHandler(ICommandHandler){
if(handler==null)返回;
this.handler=handler;
惊人的倾听();
}
/*启动侦听套接字的线程
*
*注意:在设置处理程序之前不要调用此函数!
*/
私人监听(){
线程侦听器=新线程(){
@凌驾
公开募捐{
while(receiveMessage());
handler.close();
}
};
listener.start();
}
/*在套接字上接收所有消息(响应和结果)
*
*注意:在设置处理程序之前不要调用此函数!
*
*@成功返回true,错误返回false
*/
私有布尔接收消息(){
InputStream in=null;
试一试{
in=socket.getInputStream();
Message Message=(Message)ser.deserialize(在Message.class中);
if(message==null)返回false;
if(message.containsCommand()){
//处理接收命令
Command com=message.getCommand();
CommandResult res=handler.handle(com);
编写(新消息(res));
}else if(message.containsResult()){
//处理接收结果
CommandResult res=message.getResult();
完成预定(res);
}否则{
//命令和结果都不是。。。?
返回false;
}
}捕获(IOE异常){
e、 printStackTrace();
返回false;
}
返回true;
}
//--------------------------
//线程安全IO操作
私有无效写入(消息mes)引发IOException{
OutputStream out=socket.getOutputStream();
socketWriteLock.lock();
序列(输出,mes);
socketWriteLock.unlock();
}
//----------------------------------
//线程安全保留操作
private-wrapper-reserveResult(命令com){
AwaitWrapper delayedResult=新的AwaitWrapper();
resultsLock.lock();
preservations.put(com.getUUID(),delayedResult);
resultsLock.unlock();
返回延迟结果;
}
私人预订(CommandResult){
resultsLock.lock();
reservations.get(res.getUUID()).setResource(res);
resultsLock.unlock();
}
私有无效删除保留(命令com){
resultsLock.lock();
remove(com.getUUID());
resultsLock.unlock();
}
//-------------------------------------------------------------------
//杂烩