第二十一章网络通信总结

21.1------网络程序设计基础

网络程序设计编写得到是与其他计算机进行通信的程序

21.1.1------局域网与互联网

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

21.1.2------网络协议

网络协议规定了计算机之间连接的物理、机械 (网线与网卡的连接规定)、 电气 (有效的电平范围)等特征,计算机之间的相互寻址规则,数据发送冲突的解决方式,长数据如何分段传送与接收等内容

就像不同的国家有不同的法律一样,目前网络协议也有多种。下面简单地介绍几个常用的网络协议,

1.IP协议

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

2.TCP与UDP协议

在 TCP/IP 协议栈中,有两个高级协议是网络应用程序编写者应该了解的,即传输控制协议

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

HTTP、FTP和 Telnet 等都需要使用可靠的通信频道。例如,HTTP从某个URL读取数据时,如果收到的数据顺序与发送时不相同,可能就会出现一个混乱的HTML文件或是一些无效的信息。UDP是无连接通信协议,不保证数据的可靠传输,但能够向若干个目标发送数据,或接收来自*干个源的数据。UDP以独立发送数据包的方式进行。这种方式就像邮递员送信给收信人,可以寄出多信给同一个人,且每一封信都是相对独立的,各封信送达的顺序并不重要,收信人接收信件的顺它不能保证与寄出信件的顺序相同。

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

21.1.3------端口与套接字

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

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

网络程序中的套接字(Socket)用于将应用程序与端口连接起来。套接字是一个假想的连接装置就像插座一样可连接电器与电线,如图 21.4所示。Java 将套接字抽象化为类,程序设计者只需创建 Socket类对象,即可使用套接字。

21.2------TCP程序

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

21.2.1------InetAddress类

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

netAddress 类的常用方法如表 21.1 所示。

例题1

java 复制代码
import java.net.InetAddress;
import java.net.UnknownHostException;
 
public class Address {
	public static void main(String[] args) {
		InetAddress ip;	//创建InetAddress对象
		try {//捕捉异常
				ip=InetAddress.getLocalHost();//实例化对象
				String ming=ip.getHostName();//获取本机名
				String dizi=ip.getHostAddress();//获取本机地址
				System.out.println("本机名:"+ming);//输出本机名
				System.out.println("本机IP地址:"+dizi);//将本机IP地址输出
			} catch (UnknownHostException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();//输出异常
			}
		
 
	}

21.2.2------ServerSocket类

java,net 包中的 ServerSocket 类用于表示服务器套接字,其主要功能是等待来自网络上的"请求"它可通过指定的端口来等待连接的套接字。服务器套接字一次可以与一个套接字连接。如果多台客户机同时提出连接请求,服务器套接字会将请求连接的客户机存入列队中,然后从中取出一个套接字.与服务器新建的套接字连接起来。若请求连接数大于最大容纳数,则多出的连接请求被拒绝。队列的默认大小是 50。

表21.2------ServerSocket类的常用方法

21.2.3------TCP网络程序设计

明白了TCP 程序工作的过程,就可以编写 TCP 服务器程序了。在网络编程中,如果只要求客户机疆务器发送消息,不要求服务器向客户机发送消息,称为单向通信。客户机套接字和服务器套接字接成功后,客户机通过输出流发送数据,服务器则通过输入流接收数据。下面是简单的单向通信的

例题2
java 复制代码
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(); // 启动服务器
	}
}

2

java 复制代码
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(""); // 将文本框清空
			}
		});
	}
 
	private void connect() { // 连接服务器方法
		area.append("尝试连接\n"); // 文本域中提示信息
		try {
			socket = new Socket("127.0.0.1", 8998); // 连接本地计算机的8998端口
			writer = new PrintWriter(socket.getOutputStream(), true);
			area.append("完成连接\n");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
 
	public static void main(String[] args) {
		MyClient clien = new MyClient();
		clien.setSize(200, 200); // 窗体大小
		clien.setVisible(true); // 显示窗体
		clien.connect(); // 连接服务器
	}
}

21.3------UDP程序

用户数据报协议(UDP) 是网络信息传输的另一种形式。基于 UDP 的通信和基于 TCP 的通信不同,基于 UDP的信息传递更快,但不提供可靠性保证。使用 UDP 传递数据时,用户无法知道数据能否正确地到达主机,也不能确定到达目的地的顺序是否和发送的顺序相同。虽然 UDP 是一种不可靠的协议,但如果需要较快地传输信息,并能容忍小的错误,可以考虑使用 UDP。

21.3.1------DatagramPacket类

第一种构造方法在创建 DatagramPacket 对象时,指定了数据包的内存空间和大小。第二种构造方法不仅指定了数据包的内存空间和大小,还指定了数据包的目标地址和端口。在发送数据时,必须指定接收方的 Socket 地址和端口号,因此使用第二种构造方法可创建发送数据的 DatagramPacket对象

第一种构造方法创建 DatagramSocket 对象,构造数据报套接字,并将其绑定到本地主机任何可用的端口上。第二种构造方法创建 DatagramSocket 对象,创建数据报套接字,并将其绑定到本地主机的指定端口上。第三种构造方法创建 DatagramSocket 对象,创建数据报套接字,并将其绑定到指定的端口和指定的本地地址上。第三种构造函数适用于有多块网卡和多个IP 地址的情况。

如果接收数据时必须指定一个端口号,不允许系统随机产生,此时可以使用第二种构造方法。比如有个朋友要你给他写信,那他的地址就必须确定,不确定是不行的。在发送数据时通常使用第一种构造方法,不指定端口号,而是系统为我们分配一个端口号,就像寄信不需要到指定的邮局去寄一样

21.3.2------DatagramSocket类

21.3.3------UDP网络程序设计

根据前面所讲的网络编程的基本知识以及 UDP 网络编程的特点,下面创建一个广播数据报程序广播数据报是一项较新的技术,其原理类似于电台广播。广播电台需要在指定的波段和频率上广播信息,收听者也要将收音机调到指定的波段、频率,才可以收听广播内容

例题3

java 复制代码
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
 
public class Notification extends Thread{
	String weather ="节目预报,八点有大型晚会,请及时收听";	//发送信息
	int port =9898;
	InetAddress iaddress =null;
	MulticastSocket socket = null;	//多点广播套接字
	
	Notification(){
		try {
			iaddress =InetAddress.getByName("224.255.10.0");
			socket = new MulticastSocket(port);
			socket.setTimeToLive(1);
			socket.joinGroup(iaddress);
		}catch(IOException e) {
			e.printStackTrace();
		}
	}
	public void run() {
		while(true) {
			DatagramPacket packet = null;
			byte data[] = weather.getBytes();
			packet = new DatagramPacket(data,data.length,port);
			System.out.println(weather);
			try {
				socket.send(packet);
				sleep(3000);
			}catch(IOException e) {
				e.printStackTrace();
			}catch(InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	public static void main(String[] args) {
		Notification w= new Notification();
		w.start();
	}
}
java 复制代码
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import java.net.*;
import javax.swing.*;
 
public class Receive extends JFrame implements Runnable,ActionListener {
	int port;
	InetAddress group=null;
	MulticastSocket socket=null;
	JButton inceBtn=new JButton("开始接收");
	JButton stopBtn=new JButton("停止接收");
	JTextArea inceAr=new JTextArea(10,10);
	JTextArea inced=new JTextArea(10,10);
	Thread thread;
	boolean stop=false;
	
	public Receive() {
		setTitle("广播数据报");
		setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		thread=new Thread(this);
		inceBtn.addActionListener(this);
		stopBtn.addActionListener(this);
		inceAr.setForeground(Color.blue);
		JPanel north=new JPanel();
		north.add(inceBtn);
		north.add(stopBtn);
		add(north,BorderLayout.NORTH);
		JPanel center=new JPanel();
		center.setLayout(new GridLayout(1,2));
		center.add(inceAr);
		center.add(inced);
		add(center,BorderLayout.CENTER);
		validate();
		port=9898;
		try {
			group=InetAddress.getByName("224.255.10.0");
			socket=new MulticastSocket(port);
			socket.joinGroup(group);
		}catch(IOException e) {
			e.printStackTrace();
		}
		setBounds(100,50,360,380);
		setVisible(true);
	}
	
	public void run() {
		while(!stop) {
			byte data[]=new byte[1024];
			DatagramPacket packet=null;
			packet=new DatagramPacket(data,data.length,group,port);
			try {
				socket.receive(packet);
				String message=new String(packet.getData(),0,packet.getLength());
				inceAr.setText("正在接收的内容:\n"+message);
				inced.append(message+"\n");
			}catch(IOException e) {
				e.printStackTrace();
			}
		}
	}
	public void actionPerformed(ActionEvent e) {
		if(e.getSource()==inceBtn) {
			inceBtn.setBackground(Color.red);
			stopBtn.setBackground(Color.yellow);
			if(!(thread.isAlive())) {
				thread=new Thread(this);
			}
			thread.start();
			stop=false;
		}
		if(e.getSource()==stopBtn) {
			inceBtn.setBackground(Color.yellow);
			stopBtn.setBackground(Color.red);
			stop=true;
		}
	}
	
	public static void main(String[] args) {
		Receive rec=new Receive();
		rec.setSize(460,200);
	}
}
相关推荐
李慕婉学姐6 小时前
【开题答辩过程】以《基于JAVA的校园即时配送系统的设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
java·开发语言·数据库
奋进的芋圆8 小时前
Java 延时任务实现方案详解(适用于 Spring Boot 3)
java·spring boot·redis·rabbitmq
sxlishaobin8 小时前
设计模式之桥接模式
java·设计模式·桥接模式
model20058 小时前
alibaba linux3 系统盘网站迁移数据盘
java·服务器·前端
荒诞硬汉8 小时前
JavaBean相关补充
java·开发语言
提笔忘字的帝国8 小时前
【教程】macOS 如何完全卸载 Java 开发环境
java·开发语言·macos
2501_941882489 小时前
从灰度发布到流量切分的互联网工程语法控制与多语言实现实践思路随笔分享
java·开发语言
華勳全栈9 小时前
两天开发完成智能体平台
java·spring·go
alonewolf_999 小时前
Spring MVC重点功能底层源码深度解析
java·spring·mvc
沛沛老爹9 小时前
Java泛型擦除:原理、实践与应对策略
java·开发语言·人工智能·企业开发·发展趋势·技术原理