`

Java网络编程笔记——Socket用法详解

 
阅读更多

Socket笔记——Socket用法详解

       在客户/服务器通信模式中,客户端需要主动创建与服务器连接的Socket,服务器端接收到了客户端的连接请求,也会创建与客户点的连接Socket。Socket可以看作是通信连接两端的收发器,服务器与客户端都通过Socket来收发数据。

构造Socket

Socket() //通过系统默认类型的 SocketImpl 创建未连接套接字 

Socket(InetAddress address, int port)//创建一个流套接字并将其连接到指定 IP 地址的指定端口号。 

Socket(InetAddress address, int port, InetAddress localAddr, int localPort) //创建一个套接字并将其连接到指定远程地址上的指定远程端口。 

 

设置等待建立连接的超时时间

       当客户端的Socket构造方法请求与服务器连接时,可能需要等待一段时间。默认情况下,Socket构造方法会一直等待下去,知道连接成功,或者出现异常。Socket构造方法请求连接时,受底层网络的传输速度影响,可能会处于长时间的等待状态。

如果希望限定等待连接的时间,需要设置建立连接的超时时间,此时需要一个不带啊承诺书的构造方法:

Socket socke = new Socket();

SocketAddress remoteAddr = new InetSocketAddress("localhost":8000);

socket.connect(remoteAddr,60000);//等待建立连接超时时间为1分钟

如果程序在1分钟内成功连接,则connect()方法顺利返回;如果在1分钟内出现某种异常,则抛出该异常;如果超过1分钟,既没有连接成功,也没有出现其他异常,则会抛出SocketTimeoutException。Socket类的connect(SocketAddress endpoint,int timeout)方法负责连接服务器,参数endpoint指定服务器地址,参数timeout设定超市时间,以毫秒为单位,如果参数timeout设为0,表示永远不会超时

 

设定服务器地址:

       Socket除了一个不带参数的构造方法,其它的构造方法都需在参数中设定服务器的地址,包括服务器的IP地址或者主机名,以及端口:

Socket(InetAddress address,int port)//第一个参数address表示主机的IP地址

Socket(String host,int port)//第一个参数host代表主机的名字

InetAddress类表示服务器的IP地址,InetAddress类提供了一系列静态方法,用于构造自身实例,例如:

//返回本地主机IP地址

InetAddress addrl = InetAddress.getLocalHost();

//返回“222.23.2.2”的IP地址

InetAddress addr2 = InetAddress.getByName("222.23.2.2);

//返回域名为www.googel.com的ip地址

InetAddress addr3 = InetAddress.getByName("www.googel.com");

 

设定客户端的地址

       在一个Socket对象中,既保包含了远程服务器的IP地址和端口信息,也柏涵了本地客户端的IP地址和端口信息。默认情况下客户端的IP地址来自于客户端程序所在的主机。客户端的端口地址则来自于操作系统的随机分配。

Socket类还有两个构造方法允许显示地设置客户端的IP地址和端口

Socket(InetAddress address, int port, InetAddress localAddr, int localPort) 

          创建一个套接字并将其连接到指定远程地址上的指定远程端口。

如果一个主机同时属于两个以上的网络,它就可能拥有连个以上的IP地址。

 

获得Socket信息:

getInetAddress():获得远程服务器的IP地址

getPort():获得远程服务器的端口

getLocalAddress():获得客户班底的IP地址

getInputStream():获得输入流。如果Socket还没有连接,或者已近关闭,或者已经通过shutdownInput()方法关闭输入刘,那么此方法会抛出IOException。

getOutputStream():获得输出流,如果Socket还没有连接,或者让已经关闭,或者已近通过shutDown()方法关闭输出流,那么此方法会抛出IOException

关闭Socket:

当客户端与服务器的通信借宿,应该即使关闭Socket,以释放Socket占有的包括端口在内的各种资源。Socket的close()方法负责关闭Socket。放一个Socket对象被关闭,就不能再通过他的输入流和输出流进行I/O操作,否则会导致IOException

为了确保关闭Socket的操作总是被执行,强烈建议把这个操作放在finally代码块中

 

设置Socket选项:

SO_RESUSEADDR:表示是否允许重用Socket所绑定的本地地址

SO_TIMEOUT:表示接收数据时的等待超时时间

SO_LINGER:表示当执行Socket的close方法时,是否立即关闭底层的Socket

SO_SNFBUF:表示发送数据的缓存区大小

SO_RCVBUF:表示接受数据的缓冲区大小

SO_KEEPALIVE:表示对于长时间处于空闲状态的Socket,是否要自动把它关闭。

 

TCP_NODELAY:表示立即发送数据

设置选项:public void setTcpNoDelay(boolean on)throws SocketException

读取选项: public boolean getTcpNoDelay()throws SocketException

默认情况下,发送数据采用Negale算法,Negale算法发送数据不会立即发送,而是先放在缓冲区内,等缓存区满了以后再发出去。发送完一批数据后,会等待接受放对这批数据的回应,然后才发送下一批数据。Negale适用于发送放需要发送大批量数据,并且接收方会及时做出回应的场合,这种算法通过减少传输数据的次数来提高通信效率。

不过对于GUI程序,如网络游戏程序等需要实时发送数据到服务器上,由于Negale算法采用缓冲,大大降低了实时的响应速度,导致客户程序运行很慢。

TCP_NODELAY默认值为false,表示采用Negale算法。如果调用setTcpNoDelay(true),就会关闭Sokcet的缓冲,确保数据即使发送

SO_RESUSEADDR选项

设置该选项:public void setResuseAddress(boolean on)throws SocketException

读取该选项:public void getResusAddress(boolean on)throws SocketExcpetion

当接收放通过Socket的close()方法关闭Socket时候,如果网络上还有发送到这个Socket的数据,那么底层的Socket不会释放本地端口,而是等待一段时间,确保接收到了网络上发送来的延迟数据,然后再释放端口。Socket接收到的延迟数据后,不会对这些数据做任何树立,Socket接收延迟数据的目的是,确保这些数据不会被其他碰巧绑定到同样端口的新进程接收到。

为了确保一个进程关闭Socket后,即使它还没有释放端口,同一个主机上的其他进程还可以立刻重用该端口,可以调用Socket的setResuseAddress(true)方法:

if(!socket.getResuseAddress())socket.setResuseAddress(true):

值得注意的是socket.setResuseAddress(true)方法必须在Socket还没绑定到一个本地端口之前调用,否则执行socket.getResuseAddress(true)方法无效。

SO_TIMEOUT选项

设置该选项:public void setSoTimeout(int milliseconds)throws SocketException

读取该选项: public int getSoTimeOut()throws SocketException

当通过Socket的输入流读取数据时,如果还没有数据就会等待,例如在一下代码中,in.read(buff)方法从输入流中入去1024个字节:

byte[] buff = new byte[1024];

InputStream in=socket.getInputStream();

in.read(buff);

如果输入流中没有数据,in.read(buff)就会等待发送方发送数据,知道满足一下情况才结束等待:

1)输入流中有1024个字节,read()方法把这些字节读入到buff中,再返回读取的字节数

2)当已近快接近输入流的末尾,距离末尾还有小于1024字节,read()方法会把这些字节读取到buff中,再返回读取的字节数

3)已近读到输入流的末尾,返回-1

4)连接已近断开,抛出IOException

5)如果通过Socket的setSoTimeout方法设置了等待超时时间,那么超过这一时间后抛出SocketTimeoutException

Socket类的SO_TIMEOUT选项用于设定接收数据的等待超时时间,单位为毫秒,它的默认值为0,表示会无线等待,永远不会超时

SO_LINGER选项

设置该选项:public void setSoLinger(boolean on,int seconds)throws SocketException

读取该选项:public void getSoLinger()throws SocketException

SO_LINGER选项用来控制Socket关闭时的行为,默认情况下,执行Socket的close()方法,该方法会立刻返回,但底层的Socket实际上并不会立即关闭,它会延迟一段时间,知道发送完所有剩余的数据,才会真正关闭Socket,断开连接

如果执行以下方法:socket.setSoLinger(true,0):

那么执行Socket的close()方法,该方法也会立即返回,但底层的Socket也会立刻关闭,所有为发送完的剩余数据被丢弃

SO_KEEPALIVE选项

设置该选项:public void setKeepAlive(boolean on)throws SocketException

读取该选项:public void getKeepAlive()throws SocketException

当SO_KEEPALIVE选项为true时,表示底层的TCP实现会见识该连接是否有效。如果连接处于空闲状态超过2小时,本地的TCP实现会发送一个数据包给远程的Socket。如果远程Socket没有发回响应,TCP实现就会持续尝试11分钟,知道接收到响应为止。如果12分钟内未收到响应,TCP实现会自动关闭本地Socket,端口连接,在不同的网络平台上,TCP实现尝试与远程Socket对话的时限会有所差别

 

分享到:
评论

相关推荐

    JAVA学习笔记————————

    6. **IO流**:JAVA的输入/输出流系统允许程序进行数据的读写,学习笔记会涵盖文件操作、网络通信中的数据传输,以及流的分类和使用。 7. **多线程**:JAVA提供了丰富的多线程支持,学习笔记会讲解线程的创建、同步...

    java网络编程笔记

    #### 标题解析:Java网络编程笔记 在当今数字化时代,网络编程已成为软件开发中不可或缺的一部分,尤其在J2EE(Java 2 Platform, Enterprise Edition)框架下,其重要性更为凸显。J2EE为构建企业级应用提供了强大的...

    Java NIO学习笔记——ByteBuffer用法

    在Java编程语言中,NIO(New Input/Output)是一个重要的特性,它为开发者提供了非阻塞I/O操作的能力,极大地提高了程序的性能。本文主要关注的是Java NIO中的ByteBuffer,一个关键的数据容器,用于在通道(Channel)...

    狂神Java学习笔记————前端入门——html、css、JavaScript学习代码

    【狂神Java学习笔记——前端入门——HTML、CSS、JavaScript学习代码】是针对初学者的一份详实的学习资料,这份笔记记录了跟随B站知名up主“遇见狂神说”的java系列视频中关于前端开发的基础内容。笔记内容不仅与视频...

    Python学习笔记——socket通信相关资源文件

    Python是编程领域中广泛使用的语言,特别是在网络编程方面。Socket通信是Python中实现网络通信的基础模块,它允许程序创建和管理网络连接,进行数据传输。本篇笔记将深入探讨Python中的socket通信,并结合提供的资源...

    Java学习笔记——良葛格

    Java,作为一种广泛使用的编程语言,尤其在企业级应用开发中占据着重要地位。"Java学习笔记——良葛格"是一份专为初学者设计的教程资料,由良葛格精心编写,旨在帮助读者掌握JDK5.0版本的Java基础知识。JDK(Java ...

    java 私塾课堂笔记——WebService.doc

    Java 私塾课堂笔记——WebService WebService 是一种技术,使应用程序可以以与平台和编程语言无关的方式进行相互通信。它是一个软件接口,描述了一组可以在网络上通过标准化的 XML 消息传递访问的操作。WebService ...

    Thinking in Java 自学笔记——第一章 对象导论

    Thinking in Java 自学笔记——第一章 对象导论 本章节总结了面向对象程序设计(Object-oriented Programming, OOP)的基本概念和原则,以帮助读者更好地理解 Java 编程语言。以下是对标题、描述、标签和部分内容的...

    Java Socket编程笔记_动力节点Java学院整理

    Java Socket编程是网络编程的基础,尤其对于实时应用和游戏,HTTP协议往往不能满足实时通信的需求。Socket编程提供了低级别的、面向连接的、基于字节流的通信方式,适合构建高效、可靠的网络通信。 异常处理在Java ...

    Java JDK 6学习笔记——ppt简体版.rar

    通过"Java JDK 6学习笔记——ppt简体版",学习者可以系统地学习到如何使用JDK 6进行开发,包括环境配置、基本语法、类库使用、异常处理、IO流、网络编程、多线程等各个方面。PPT格式通常直观易懂,便于快速理解和...

    JAVA网络编程

    Java网络编程基础 Datagram类使用方法 (1) .doc Java网络编程基础 InetAddress类的使用.doc Java网络编程基础 ServerSocket类使用.doc 《JAVA编程规范》.doc Java基础 三步学会Java Socket编程(一) .doc Java基础 ...

    Java JDK 6学习笔记——ppt简体版

    Java JDK 6学习笔记——PPT简体版是针对初学者和有经验的开发者们的一份宝贵资源,它深入浅出地介绍了Java编程语言的核心概念和技术。这份笔记以PPT的形式呈现,使得学习过程更加直观易懂,适合课堂教学或自我学习。...

    Java JDK 6学习笔记——ppt简体版附课本代码

    总的来说,“Java JDK 6学习笔记——ppt简体版”全面介绍了Java编程语言的基础知识和JDK 6的关键特性,结合配套的代码示例,是系统学习和掌握Java开发的宝贵资料。无论你是Java初学者还是寻求提升的老手,都能从中...

    JAVA 私塾笔记整理——反射机制(Reflection)

    Java反射机制是Java编程语言中的一个强大特性,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。这个特性使得Java具有了高度的灵活性和动态性,尤其是在处理对象、类、接口以及它们之间的关系...

    Java JDK 6学习笔记——ppt

    Java JDK 6学习笔记——PPT简体版是针对初学者和有经验的开发者们的一份宝贵资源,它深入浅出地介绍了Java编程语言的核心概念和技术。这份资料以PPT的形式呈现,使得学习过程更加直观易懂,同时包含了课程中的源代码...

    java学习笔记——异常

    Java学习笔记——异常 在Java编程中,异常处理是一项至关重要的技能,它允许开发者优雅地处理程序运行时可能遇到的问题,防止程序意外终止,并提供有用的反馈信息。异常是程序执行过程中遇到的不正常情况,例如除以...

Global site tag (gtag.js) - Google Analytics