Java网络编程之使用套接字(Socket)进行通信

朱应丽
朱应丽   编辑于 2018-12-24 16:16
阅读量: 635

一、  套接字(Scoket)的引入

        Java支持基于流的通信和基于包的通信。基于流的通信使用传输控制协议(TCP)进行数据传输,而基于包的通信使用用户数据报协议(UDP)。因为TCP协议能够发现丢失的传输信息并重新发送,所以传输过程是无损的和可靠的。相对而言,UDP协议不能保证传输没有丢失。因此,大多数Java程序设计采用基于流的通信。

        套接字可以使得程序很方便地访问TCP/IP,为了能够方便地开发网络应用,Java API提供了用于创建套接字的类来进行程序的网络通信。套接字是两台主机之间逻辑连接的端点,可以用来接收和发送数据。Java对于套接字通信的处理非常类似于对输入输出操作的处理,因此程序对套接字读写就像对文件读写一样容易。

        网络程序设计通常设计一个服务器端和一个或多个客户端。客户端向服务器端发送请求,而服务器端响应请求。客户端从尝试建立与服务器的连接开始,服务器可能接受或者拒绝这个连接。一旦建立连接,客户端和服务器端就可以通过套接字进行通信。

二、  服务器套接字

        要创建一个服务器,需要创建一个服务器套接字(Server Socket),并把它附加到一个端口上,服务器从这个端口监听连接。端口套接字上的TCP服务。端口号的范围是从0到65536,但是0到1024是系统保留的端口号。比如,电子邮件服务器运行在端口25上,web服务器通常运行在端口80上。

        可以选择任意一个当前没有被其他进程使用的端口。使用下面的语句创建一个服务器套接字,参数8000表示服务器端使用的接口:

ServerSocket ss = new ServerSocket(8000);

三、  客户端套接字

        创建服务器套接字以后,服务器可以通过使用下面的语句监听连接:

Socket socket = ss.accept();

        这个语句会一直等待,直到一个客户端连接到服务器套接字。客户端执行下面的语句,请求与服务器进行连接:

Socket s = new Socket(serverName, port);

        这条语句打开一个套接字,使得客户端程序能够与服务器进行通信。其中serverName是服务器的互联网主机名或IP地址。

四、  通过套接字进行数据传输

        服务器接受连接以后,服务器和客户端之间的通信就可以像输入输出流一样进行操作。但是对于客户端和服务器端而言输入流或输出流是相对的。

        对于客户端而言,接收服务器端的数据是输入流,向服务器端发送数据是输出流;对于服务器端来说,向客户端发送数据是输出流,接收客户端发送的数据是输入流。为了获得输入流或者输出流,可以使用套接字对象的getInputStream()方法和getOutputStream()方法。

        下面通过一个完整的例子来学习如何使用Socket进行客户端和服务器端之间的数据传输:

//服务器端

public class Server {



   public static void main(String[] args) {

      try {

         ServerSocket ss = new ServerSocket(8000);

         Socket socket = ss.accept();

         //向客户端发送数据

         OutputStream os = socket.getOutputStream();

         DataOutputStream dos = new DataOutputStream(os);

         dos.writeUTF("login");

         //接收客户端数据

         InputStream is = socket.getInputStream();

         DataInputStream dis = new DataInputStream(is);

         System.out.println("接收到客户端数据:" + dis.readUTF());

         //向客户端发送数据        

         dos.writeUTF("login successful");

         //关闭流

         is.close();

         dis.close();

         os.close();

         dos.close();

      } catch (IOException e) {

         e.printStackTrace();

      }

   }

}



//客户端

public class Client {

   public static void main(String[] args) {

      try {

         //请求连接服务器

         Socket s = new Socket("127.0.0.1", 8000);

         //接收服务器数据

         InputStream is = s.getInputStream();

         DataInputStream dis = new DataInputStream(is);

         System.out.println("接收到服务器数据:" + dis.readUTF());

         //向服务器端发送数据

         OutputStream os = s.getOutputStream();

         DataOutputStream dos = new DataOutputStream(os);

         dos.writeUTF("java");

         //接收服务器数据

         System.out.println("接收到服务器数据:" + dis.readUTF());

         //关闭流

         is.close();

         dis.close();

         os.close();

         dos.close();

      } catch (UnknownHostException e) {

         e.printStackTrace();

      } catch (IOException e) {

         e.printStackTrace();

      }

   }

}

       运行此实例,需要打开两个Eclipse,分别运行Server端和Client端,并保证先执行Server端,在执行Client端。

       Server端执行结果:

接收到客户端数据:java

Client端执行结果:

接收到服务器数据:login

接收到服务器数据:login successful

        整个程序执行流程如下图所示:

收藏 转发 评论