第二十一 网络通信

目录

网络程序设计基础 

局域网与互联网

 网络协议

1.IP协议

2. TCP与UDP协议

端口与套接字

TCP程序

InetAddress 类

ServerSocket 类

TCP网络程序设计

UDP程序

DatagramPacket类

DatagramSocker 类

UDP网络程序设计

网络程序设计基础 

局域网与互联网

为了实现两台计算机的通信,必须用一个网络线路连接两台计算机。如下图所示

 网络协议

1.IP协议

IP是Internet Protocol的简称,是一种网络协议。Internet 网络采用的协议是TCP/IP协议,其全称是Transmission Control Protocol/Internet Protocol。Internet 依靠TCP/IP协议,在全球范围内实现了不同硬件结构、不同操作系统、不同网络系统间的互联。在Internet 网络上存在着数以亿计的主机,每台主机都用网络为其分配的 Internet 地址代表自己,这个地址就是I地址。到目前为止,I地址用4个字节,也就是32位的二进制数来表示,称为IPv4。为了便于使用,通常取用每个字节的十进制数,并且每个字节之间用圆点隔开来表示I地址,如192.168.1.1。现在人们正在试验使用16个字节来表示I地址,这就是IPv6,但IPv6还没有投入使用。

TCP/IP 模式是一种层次结构,共分为4层,分别为应用层、传输层、互联网层和网络层。各层实现特定的功能,提供特定的服务和访问接口,并具有相对的独立性,如图所示。

2. TCP与UDP协议

在TCPAIP 协议栈中,有两个高级协议是网络应用程序编写者应该了解的,即传输控制协议(Transmission Control Protocol,TCP)与用户数据报协议(User Datagram Protocol, UDP)。

TCP 协议是一种以固接连线为基础的协议,它提供两台计算机间可靠的数据传送。TCP可以保证数据从一端送至连接的另一端时,能够确实送达,而且抵达的数据的排列顺序和送出时的顺序相同。因此,TCP协议适合可靠性要求比较高的场合。就像拨打电话,必须先拨号给对方,等两端确定连接后,相互才能听到对方说话,也知道对方回应的是什么。

HTTP、FTP 和Telnet 等都需要使用可靠的通信频道。例如,HTTP从某个URL读取数据时,如果收到的数据顺序与发送时不相同,可能就会出现一个混乱的HTML文件或是一些无效的信息。

UDP是无连接通信协议,不保证数据的可靠传输,但能够向若干个目标发送数据,或接收来自若干个源的数据。UDP以独立发送数据包的方式进行。这种方式就像邮递员送信给收信人,可以寄出很多信给同一个人,且每一封信都是相对独立的,各封信送达的顺序并不重要,收信人接收信件的顺序也不能保证与寄出信件的顺序相同。

UDP 协议适合于一些对数据准确性要求不高,但对传输速度和时效性要求非常高的网站,如网络聊天室、在线影片等。这是由于TCP协议在认证上存在额外耗费,可能使传输速度减慢,而UDP协议即使有一小部分数据包遗失或传送顺序有所不同,也不会严重危害该项通信。

端口与套接字

一般而言,一台计算机只有单一的连到网络的物理连接(Physical Connection),所有的数据都通过此连接对内、对外送达特定的计算机,这就是端口。网络程序设计中的端口(port)并非真实的物理存在,而是一个假想的连接装置。端口被规定为一个在0~65535的整数。HTTP服务一般使用80端口,FTP 服务使用21端口。假如一台计算机提供了HTTP、FTP等多种服务,那么客户机会通过不同的端口来确定连接到服务器的哪项服务上,如图所示。

通常,0~1023的端口数用于一些知名的网络服务和应用,用户的普通网络应用程序应该使用1024以上的端口数,以避免端口号与另一个应用或系统服务所用端口冲突。

网络程序中的套接字(Socket)用于将应用程序与端口连接起来。套接字是一个假想的连接装置,就像插座一样可连接电器与电线,如图所示。

Java 将套接字抽象化为类,程序设计者只需创建Socket类对象,即可使用套接字。

TCP程序

TCP网络程序设计是指利用Socket 类编写通信程序。利用TCP协议进行通信的两个应用程序是有主次之分的,一个称为服务器程序,另一个称为客户机程序,两者的功能和编写方法大不一样。服务器端与客户端的交互过程如图所示。

服务器程序创建一个 ServerSocket(服务器端套接字)对象,调用accept0方法等待客户机来连接

客户端程序创建一个Socket对象,请求与服务器建立连接

服务器接收客户机的连接请求,同时创建一个新的Socket 对象与客户建立连接。随后服务器继续等待新的请求

InetAddress 类

java.net包中的InetAddress类是与IP地址相关的类,利用该类可以获取IP地址、主机地址等信息。

 例题21.1

import java.net.*; //导出Java.net包

public class Address { //创建类

 public static void main(String[] args) {

  InetAddress ip; //创建InetAddress对象

  try { //捕捉可能出现的异常

   ip = InetAddress.getLocalHost(); //实例化对象

   String locaIname = ip.getHostName(); //获取本机名

   String localip = ip.getHostAddress(); //获取本机IP地址

   System.out.println("本机名:"+locaIname); //将本机名输出

   System.out.println("本机名IP地址:"+localip); //将本机IP地址输出

  }catch(UnknownHostException e){

   e.printStackTrace(); //输出异常信息

  }

  

 }

}//例题21.1

运行结果如下:

ServerSocket 类

ServerSocker 类的构造方法通常会抛出1OException异常,具体有以下几种形式:

ServerSocket():创建非绑定服务器套接字。

ServerSocket(int port):创建绑定到特定端口的服务器套接字。

ServerSocket(int port, int backlog):利用指定的backlog创建服务器套接字,并将其绑定到指定的本地端口号上。

ServerSocket(int port, int backlog, InetAddress bindAddress):使用指定的端口、侦听backlog和要绑定到的本地IP地址创建服务器。这种情况适用于计算机上有多块网卡和多个I地址的情况,用户可以明确规定ServerSocket在哪块网卡或哪个IP地址上等待客户的连接请求。

ServerSocket 类的常用方法如表21.2所示。

TCP网络程序设计

例题21.2

import java.io.*;

import java.net.*;

public class MyServer {

 private ServerSocket server; // 服务器套接字

 private Socket socket; // 客户端套接字

 void start() {// 启动服务器

  try {

   server = new ServerSocket(8998); // 服务器启用8998端口

   System.out.println("服务器套接字已经创建成功");

   while (true) {

    System.out.println("等待客户端的连接");

    socket = server.accept(); // 服务器监听客户端连接

    // 根据套接字字节流创建字符输入流

    BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));

    while (true) {// 循环接受信息

     String message = reader.readLine();// 读取一行文本

     if ("exit".equals(message)) {// 如果客户端发来的内容为“exit”

      System.out.println("客户端退出");

      break;// 停止接受信息

     }

     System.out.println("客户端:" + message);

    }

    reader.close(); // 关闭流

    socket.close(); // 关闭套接字

   }

  } catch (IOException e) {

   e.printStackTrace();

  }

 }

 public static void main(String[] args) {

  MyServer tcp = new MyServer();

  tcp.start(); // 启动服务器

 }

}

//21.2

 运行结果如下:

编写客户端程序,将用户在文本框中输入的信息发送至服务端,并将文本框中输入的信息显示再客户端的文本域中。

import java.awt.*;

import java.awt.event.*;

import java.io.*;

import java.net.Socket;

import javax.swing.*;

public class MyClient extends JFrame {

 private PrintWriter writer;// 根据套接字字节流创建的字符输出流

 Socket socket; // 客户端套接字

 private JTextArea area = new JTextArea();// 展示信息的文本域

 private JTextField text = new JTextField(); // 发送信息的文本框

 public MyClient() {

  setTitle("向服务器送数据");

  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

  Container c = getContentPane(); // 主容器

  JScrollPane scrollPane = new JScrollPane(area);// 滚动面板

  getContentPane().add(scrollPane, BorderLayout.CENTER);

  c.add(text, "South"); // 将文本框放在窗体的下部

  text.addActionListener(new ActionListener() {// 文本框触发回车事件

   public void actionPerformed(ActionEvent e) {

    writer.println(text.getText().trim()); // 将文本框中的信息写入流

    area.append(text.getText() + '\n'); // 将文本框中的信息显示在文本域中

    text.setText(""); // 将
 

你可能感兴趣的:(java)