Java中的网路程序设计

来源:互联网 发布:python 小世界理论 编辑:程序博客网 时间:2024/05/18 02:12

Java中基于TCP/IP的网路程序设计主要由以下几个类来实现,

1,,InetAdderss,主要的作用是设置IP地址,该类有若干个构造函数,以及一些静态的方法,详细的信息可见JDK参考文档,比较常用的几个方法如下,

public String getHostAdderss();

public synchronized static InetAdderss getLocalHost();

public static InetAddress getByName(String host);

以上方法会抛出UnknownHostException

 

2,,,ServerSocekt,主要用于服务器端得程序设计中,首先建立一个ServerSocket类的对象,该类有若干个构造函数,

如下:

public ServerSocket(int port);

public ServerSocket(int port,int backlog);

public ServerSocket(int port,int backlog,InetAdderss bindAddr);

以上方法会抛出IOException异常

 

当建立起了服务器端的监听套接字之后就可以调用socket的accept方法来接受连接的请求,该方法会返回一个Socket对象代表与客户机端进行通信的套接字,

 

 

 

3,,,Socket,,主要用于客户端,用来与服务器端进行通信,也用于服务器端,用来接受服务器端调用accept返回的套接字,与客户机进行通信,该类的构造方法主要有以下几个重载的方法

public Socket();

public Socket(InetAddress address,int port);

public Socket(InetAddress address,int port,InetAddress localAddress,int port);

public Socket(String host,int port);

public Socket(String host,int port,InetAddress local,int localport);

以上方法都会抛出IOException异常,除了第一个方法之外都会主动的与服务器进行连接,

 

该类还可以设置以下几个方法

3.1设置连接等待时间

可以设置连接的等待时间,如果在等待时间到达后仍然没有连接成功则抛出异常用法如下

Socket socket=new Socket();

SocketAddress remoteAddr=new InetAddress("localhost",8000);

socket.connect(remoteAddr,60000);//等待1分钟,如果在一分钟内没有连接成功则抛出SocketTimeOutException异常

3.2获取Socket的信息

可以调用getInetAddress()来获取远程服务器的IP地址等信息,

调用getInputStream()来获取输入流

调用getOutputStream()来获取输出流

调用getLocalPort()来获取本地的端口

调用getLocalHost()来获取本地的IP地址

3.3关闭Socket

当客户机与服务器通信终结的时候应该调用socket的close方法来关闭socket,以释放socekt占用的各种资源

同时socket提供了几个方法来测试socket是否已经关闭,如isClosed(),isConnect(),isBound()等,

3。4

当通过socket通信的时候如何判断对方已经关闭了?可以有以下几种方式来进行判断

1,以约定的特殊字符来作为通信结束的标志,如bye

2,进程A首先发送一个消息告诉B,其所发送的正文的长度,再发送正文

3,当A发送完所用的数据,关闭socket后当进程B再次执行到read()方法的时候会返回-1,若执行bufferedreader的readline方法的时候回返回null

4,当调用socket的close方法时会关闭其输入输出流,有时候仅仅希望关闭输入输出流其中之一,此时可以采用socket提供的半关闭方法,shutdownInput()关闭输入流, 或者shutdownOutput()关闭输出流,

 

总之在发送方没有关闭socket的情况下突然就结束了运行,则接收方在执行到readline方法的时候会跑出SocketException :connection reset异常,若发送方先关闭socket或者输出流后再结束运行,那么接收方的readline会读到null,read会返回-1;

 

4,,Socket的若干个选项

Socket有若干个选项,来控制Socket的各种行为

4.1 TCP_NODELAY,,是否立即发送数据

可以通过setTcpNoDelay(boolean on)来设置,在默认情况下该值为false,表示采用缓冲的方式来进行通信,适用于发送方要发送大批的数据,且接收方会及时的作出回应的场合,

 

4.2, SO_RESUSEADDR  用来设置端口是否立即可用

可以用setResuseAddress(boolean on)方法来设置

一般接收方通过socket的close方法关闭socket时候,若网路还有数据传送到该socket,则底层的socket不会立即的释放掉本地端口,而是等待一段时间之后,确保接收到网路上发过来的数据后在释放端口,默认值为false,,可以采用set方法来设置该值来表示同一主机上的其他进程可以立即的重用该端口

 

4.3 SO_TIMEOUT 用来设置超时的时间

setSoTimeout(int milliseconds);

如下,byte[] buff=new byte[1024];'

in.read(buff);

若流中有1024个字节,read方法会等待这些数据读入buffer中后返回读取的字节数

若已经快要到流的结尾的时候,read会将这些字节读入buffer中返回读取的字节数

若已经到流的结尾的时候,会返回-1

若连接已经断开则会抛出IOException异常

若设置了setTimeout等待时间,这超出这一时间后会抛出SocketTimeoutException异常,当抛出异常后Socekt依然可用,可以尝试再次的连接,

 

4.4 SO_LINGER

setSoLinger(boolean on,int seconds);用来控制Socket的默认行为

默认的情况下执行socket的close方法时候会立即的返回,但是底层的socket并没有关闭,而是延迟一段时间后直到所有的剩余数据发送完,若执行了setSoLinger(true,0),则执行完socket的close方法时会立即返回,且底层的socket会立即关闭,废弃未发完的数据,

 

4.5 SO_RCVBUF 用于设置输入的数据的缓冲区大小

void setRecvBufferSize(int size);

 

4.6 SO_SNDBUF    用于输出的数据缓冲区的大小

void setSendBufferSize(int size)

 

4.7 SO_KEEPALIVE  标示连接是否有效

当该选项为true时,标示底层的TCP实现会监视该连接是否有效,当处于空闲的连接状态持续两个小时的时候本地的socket会发送一个数据包给远程的socekt,若远程的socket没有回应则,本地的socekt会持续尝试11分钟,直到接收到响应为止,若在12分钟内无响应,则tcp实现会自动的关闭本地的socket,断开连接,该选项的默认值为false,标示不会监视tcp连接的有效性,,,