使用Socket进行通信
客户端通常可使用Socket的构造器来连接到指定服务器Socket通常可使用如下两个构造器
Socket(InetAddress/String remoteAddress int port)创建连接到指定远程主机远程端口的Socket该构造器没有指定本地地址本地端口默认使用本地主机的默认IP地址默认使用系统动态指定的IP地址
Socket(InetAddress/String remoteAddress int port InetAddress localAddr int localPort)创建连接到指定远程主机远程端口的Socket并指定本地IP地址和本地端口号适用于本地主机有多个IP地址的情形
上面两个构造器中指定远程主机时既可使用InetAddress来指定也可直接使用String对象来指定但程序通常使用String对象(如)来指定远程IP当本地主机只有一个IP地址时使用第一个方法更为简单如下代码所示
//创建连接到本机端口的Socket
Socket s = new Socket( )
//下面就可以使用Socket进行通信了
…
当程序执行上面代码中粗体字代码时该代码将会连接到指定服务器让服务器端的ServerSocket的accept()方法向下执行于是服务器端和客户端就产生一对互相连接的Socket
上面程序连接到远程主机的IP地址使用的是这个IP地址是一个特殊的地址它总是代表本级的IP地址因为笔者示例程序的服务器端客户端都是在本机运行所以Socket连接到远程主机的IP地址使用
当客户端服务器端产生了对应的Socket之后此时就到了如图所示的通信示意图程序无须再区分服务器客户端而是通过各自的Socket进行通信Socket提供如下两个方法来获取输入流和输出流
InputStream getInputStream()返回该Socket对象对应的输入流让程序通过该输入流从Socket中取出数据
OutputStream getOutputStream()返回该Socket对象对应的输出流让程序通过该输出流向Socket中输出数据
看到这两个方法返回的InputStream和OutputStream读者应该可以明白Java在设计IO体系上的苦心了不管底层的IO流是怎样的节点流文件流也好网络Socket产生的流也好程序都可以将其包装成处理流从而提供更多方便的处理下面以一个最简单的网络通信程序为例来介绍基于TCP协议的网络通信
下面的服务器程序非常简单它仅仅建立ServerSocket监听并使用Socket获取输出流输出
程序清单codes///Serverjava
public class Server
{
public static void main(String[] args)
throws IOException
{
//创建一个ServerSocket用于监听客户端Socket的连接请求
ServerSocket ss = new ServerSocket()
//采用循环不断接受来自客户端的请求
while (true)
{
//每当接受到客户端Socket的请求服务器端也对应产生一个Socket
Socket s = ssaccept()
//将Socket对应的输出流包装成PrintStream
PrintStream ps = new PrintStream(sgetOutputStream())
//进行普通IO操作
psprintln(您好您收到了服务器的新年祝福!)
//关闭输出流关闭Socket
psclose()
sclose()
}
}
}
下面的客户端程序也非常简单它仅仅使用Socket建立与指定IP指定端口的连接并使用Socket获取输入流读取数据
[] []