`
histan
  • 浏览: 15489 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

关于Socket的一个异常

阅读更多
    近日在无聊,写了一些关于socket通讯的demo,结果出现了一个Connection rest 异常信息,然后看了一下源码
此异常的出现,是在java.net.SocketInputStream中抛出来的,首先来看一下源码:
 
class SocketInputStream extends FileInputStream
	{
   		 static {
       	 init();
   	 	}
    
   	 private boolean eof;
   	 private PlainSocketImpl impl = null;
    	 private byte temp[]; 
    	 private Socket socket = null;
	

	/*********

			部分省略
				************/
	if (impl.isConnectionReset()) {     /*异常由此处抛出*/
	    throw new SocketException("Connection reset");
	}



由此可见,是因为调用方法的时候触发了 PlainSocketImpl中的 isConnectionReset()方法,继续寻根问底,看看到底isConnectionReset()做了
什么操作,继续看代码:
class PlainSocketImpl extends SocketImpl
{
    /*

	**
		**  部分代码省略 *****/
    
    private int resetState;
    private int CONNECTION_RESET = 2;
    private Object resetLock = new Object();


	public boolean isConnectionReset() {
	synchronized (resetLock) {
	    return (resetState == CONNECTION_RESET);
	}
    }
	/*

		**
			**  部分代码省略 *****/
}




仔细看,在isConnectionReset方法中 对创建的对象流进行了加锁?然后注释都没有写这个地方用来干嘛的?????
而且大家仔细看下,这个类名不是public的,在类的注释中有这样一句话:         
This implementation does not implement any security checks.
对这些很是不解,其中有一句这样的代码:
private Object resetLock = new Object();
这些东西看起来只是对他进行了安全控制,用的同步的方法,为什么这么弄?原本是想把问题好好搞明白,结果越看越深,更迷糊了,后面又继续查看源代码就有
  java.net.SocketImpl
     * @see        java.net.SocketImplFactory#createSocketImpl()
     * @see        java.net.ServerSocket#setSocketFactory(java.net.SocketImplFactory)
     * @see        SecurityManager#checkListen
这些了,看来还得找多点时间好好研究一下才会使问题得到解决,并对此有更深的体会。
分享到:
评论
3 楼 histan 2010-04-16  
FeiXing2008 写道
近来也在做Socket开发。
明天再试试这个东西。

呵呵,谢谢yechw
2 楼 FeiXing2008 2010-04-11  
近来也在做Socket开发。
明天再试试这个东西。
1 楼 yechw 2010-04-11  
这个叫虚拟锁。

通常我们对一个类A中的两个方法进行同步操作是在方法上加锁:
public synchronized boolean methodA() {
            /*省略*/
    }

public synchronized boolean methodB() {
            /*省略*/
    }


在这种情况下,多个线程分别同时调用A实例的methodA(),methodB()方法时,只有一个线程可以获得同步锁,执行一个方法,其他线程需要等待这个线程释放锁了再竞争同步锁,执行他们要执行的方法。

这通常是在methodA和methodB方法中存在对相同共享数据的情况下,为了避免数据的争用而采用的同步操作。如果说这两个方法之间不存在资源争用,但又都需要同步的时候,如PlainSocketImpl类中的releaseFD()和isConnectionReset()这两个方法,你仔细看一下PlainSocketImpl的代码:
class PlainSocketImpl extends SocketImpl {
    /*省略*/
    private Object fdLock = new Object();
    /*省略*/
    private Object resetLock = new Object();
    /*省略*/
    public final void releaseFD() {
        synchronized (fdLock) {
            fdUseCount--;
            if (fdUseCount == -1) {
                if (fd != null) {
                    try {
                        socketClose();
                    } catch (IOException e) {
                    } finally {
                        fd = null;
                    }
                }
            }
        }
    }

    public boolean isConnectionReset() {
        synchronized (resetLock) {
            return (resetState == CONNECTION_RESET);
        }
    }
    /*省略*/
}


如果采用前面这种对方法或者对类的同步,那么假设A线程在执行PlainSocketImpl实例的releaseFD()时,B线程需要执行PlainSocketImpl实例的isConnectionReset()方法,就需要等待A线程释放同步锁,这种等待是无意义的。

为了解决这个问题,PlainSocketImpl类采用了后面这种虚拟锁的手段,创建了两个虚拟锁对象fdLock和resetLock并分别同步,这样在两个线程分别调用这两个方法时,他们获得的是不同对象的锁,互相没有任何竞争,就可以同步运行,只有两个线程同时调用releaseFD()或isConnectionReset()方法时才会争用同一个锁。

相关推荐

    Socket 异常通信实例

    综上所述,这个实例不仅涉及了Socket的基础应用,还涵盖了同步和异步通信模式,以及在实际应用中如何保障通信安全,对于初学者来说,这是一个很好的实践案例,可以帮助他们深入理解和掌握Socket编程的精髓。

    socket通信异常解决总结

    如果在指定的时间内没有数据传送,会给对端发送一个 Keep-Alive 数据报,对端如果收到这个数据,回送一个 TCP 的 ACK,确认这个字节已经收到,这样就知道此连接没有被断开。如果一段时间没有收到对方的响应,会进行...

    Socket长连接异常处理

    在 Java 网络编程中,Socket 长连接是指在客户端和服务器端之间保持一个长期的连接,以便于数据的传输和通信。然而,在这种长连接中,可能会出现各种异常情况,影响到数据的传输和通信。下面将详细介绍这些异常情况...

    利用Keep-Alive处理Socket网络异常断开的方法

    2. **探测报文**:TCP协议会发送一个特殊的Keep-Alive数据包给对方,这个数据包使用的是上一次发送的数据的序列号。 3. **响应**:如果对端接收到这个数据包,则会发送一个ACK确认报文回来,表明连接仍然有效。 4....

    c++实现socket:一个服务器对应多个客户端相互传递信息

    描述中的"一个socket对应多个client,每个socket开启一个新的线程"表明服务器会为每个新的客户端连接创建一个新的socket实例,并且在一个单独的线程中运行,这样就可以避免因一个客户端的阻塞操作(如等待输入)而...

    Java+Socket+网络编程常见异常

    Java+Socket+网络编程常见异常

    Socket常见异常

    在 Socket 类中有很多方法在声明时使用throws 抛出了一些异常,这些异常都是 IOException 的子类。在Socket 类的方法中抛出最多的就是SocketException,其余还有七个异常可供Socket 类的方法抛出。

    C#socket通讯两个最经典错误解决方案

    在网络编程中,常见的一个问题是当 Server 或 Client 中的一方主动断开连接时,另一方可能会遇到 “远程主机强迫关闭了一个现有连接” 的异常。这会导致程序异常终止,无法继续执行后续逻辑。 **问题叙述** 当一方...

    关于socket的封装使用

    Socket是网络编程中的一个重要概念,它是基于TCP/IP通信协议实现的一种通信方式,允许两台计算机通过互联网进行双向通信。在Android开发中,我们经常会用到Socket进行客户端与服务器端的数据交换。下面将详细介绍...

    java socket类的异常总结

    NULL 博文链接:https://jiaguwen123.iteye.com/blog/1356153

    Unity做的一个关于Socket的小案例

    对于Client,同样可以创建一个Socket实例,然后使用`Connect`方法连接到Server。 2. 设置服务器的IP和端口:`IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, 9999);` 这里9999是自定义的端口号,IPAddress...

    socket一个简单的程序

    在这个名为"socket一个简单的程序"的示例中,我们将会探讨如何构建一个基础的客户端和服务端模型,这对于理解Socket工作原理及其在实际开发中的应用至关重要。 首先,让我们了解什么是Socket。Socket,即套接字,是...

    一个简单的socket数据收发程序

    本教程将探讨一个基于MFC(Microsoft Foundation Classes)的Socket应用程序,它由一个服务器端(Server)和一个客户端(Client)组成,用于实现简单数据的收发。 首先,我们要了解什么是Socket。Socket是网络上的...

    socketdemo 一个用来学习socket入门的例子

    SocketDemo 是一个专门为Java初学者设计的用于学习和理解Socket通信基础的实例项目。Socket编程是网络编程的重要组成部分,它提供了进程间通过网络进行通信的能力。在这个例子中,我们将深入探讨Socket编程的基本...

    一个简单的socket服务器应用

    在IT行业中,网络编程是不可或缺的一部分,而Java作为一种多平台支持的语言,...这个简单的服务器应用提供了一个起点,通过它,你可以进一步探索网络编程的广阔天地,如TCP/IP协议、异常处理、数据编码解码等复杂主题。

    socket客户端,可连接多个服务器

    在这个特定的场景中,我们讨论的是一个设计为连接多个服务器的Socket客户端。这个客户端程序能够向多个服务端发送消息,并且在消息中携带自身的ID,以便服务端识别消息来源。此外,它还具备了自动重连功能,即在非...

    C++ vs下用socket实现的多组一对一通信

    服务器端通常会启动一个监听Socket,调用`bind()`函数绑定到特定的IP地址和端口,然后调用`listen()`开始监听。每当有新的连接请求,服务器调用`accept()`函数接受连接,并为每个连接创建一个新的Socket来处理通信。...

    socket编程实例,客户端和服务器端一对一信息传输

    在这个"socket编程实例,客户端和服务器端一对一信息传输"的示例中,我们将会探讨如何在Microsoft Visual C++ (VC++)环境下利用Socket API来构建一个简单的点对点通信系统。 首先,我们要了解Socket的基本概念。...

    c# socket编程 一个简单的模拟QQ聊天软件 可以群聊

    本项目“C# Socket编程:一个简单的模拟QQ聊天软件”就是一个很好的示例,它展示了如何利用Socket实现多人在线聊天功能,类似于QQ的群聊。 首先,让我们深入了解Socket。Socket是网络通信的基础,它为应用程序提供...

    Socket模拟服务器_Socket模拟服务器_

    要创建一个Socket模拟服务器,首先我们需要创建一个ServerSocket实例,并指定一个端口号。例如: ```java ServerSocket serverSocket = new ServerSocket(8888); ``` 这里的8888是服务器监听的端口号,必须确保该...

Global site tag (gtag.js) - Google Analytics