黑马程序员——Java基础之网络编程

-----------android培训java培训、java学习型技术博客、期待与您交流!------------


Java基础之网络编程

1.网络编程基本概念

         网络编程的本质是两个设备之间通过网络的数据交换,在计算机网络中,设备主要指计算 机。概括的说是把一个设备中的数据发送给另外的一个设备,然后 接受另外一个设备反馈的数据。现在的网络编程基本上都是基于请求/响应方式的,也就是一个设备发送请求数据给另外一个,然后接收另一个设备的反馈。

       在网络编程中,发起连接程序,也就是发送第一次请求的程序,被称作客户端(Client),等待其他程序连接的程序被称作服务器(Server)。客户端程序可以在需要的时候启动,而服务器为了能够时刻相应连接,则需要一直启动。

       例如以打电话为例,首先拨号的人类似于客户端,接听电话的人必须保持电话畅通类似于服务器。连接一旦建立以后,就客户端和服务器端就可以进行数据传递了,而且两者的身份是等价的。在一些程序中,程序既有客户端功能也有服务器端功能,最常见的软件就是 BT、emule 这类软件了。

网络模型(如下图)

    OSI参考模型

   TCP/IP参考模型

2、网络通讯要素

IP地址:

InetAddres:网络中设备的标识,不易记忆,可用主机名;

    本地回环地址:127.0.0.1 主机名:localhost;

端口号:

用于标识进程的逻辑地址,不同进程的标识

    有效端口:0~65535,其中0~1024系统使用或保留端口。

    备注:不是所谓的物理端口!

传输协议:通讯的规则

常见协议:TCP,UDP。

 

3、TCP和UDP的联系和用途

一.区别:

二者都是有用的和常用的,可直接从功能上进行区分,简单明了:

        a.这两种传输协议也就是合于适配不同的业务和不同的硬件终端。在使用中,类似于图像、声音等对可靠性要求没有那么高的业务可以用UDP,他们不 需要准确存储对准确性无要求但要求速度快;类似于文本、程序、文件等要求可靠的数据最好就用TCP,但会牺牲一些速度,对系统资源的要求:CP较多,UDP少。

        b.程序结构:UDP程序结构较简单,TCP复杂。流模式与数据报模式:TCP保证数据正确性,UDP可能丢包;TCP保证数据顺序,UDP不保证。

二.用途

        TCP是面向连接的,有比较高的可靠性,一些要求比较高的服务一般使用这个协议,如FTP、Telnet、SMTP、HTTP、POP3等,而UDP是面向无连接的,使用这个协议的常见服务有DNS、SNMP、QQ等。对于QQ必须另外说明一下,QQ2003 以前是只使用UDP协议的,其服务器使用8000端口,侦听是否有信息传来,客户端使用4000端口,向外发送信息(这也就不难理解在一般的显IP的QQ版本中显示好友的IP地址信息中端口 常为4000或其后续端口的原因了),即QQ程序既接受服务又提供服务,在以后的QQ版本中也支持使用TCP协议了。

Udp是一种面向无连接的通信协议,该协议使得数据传输的速度得到大幅度的提高。视频聊天语音聊天基本都是用UPD协议。

2.网络编主要的类

    网络编程用来的API主要在java.net包中,根据通讯规则不同,可以进行分类如下:


2.UPD通讯规则下的编程

基本步骤:

服务端:

*  建立一个UDP的socket服务,要明一个端口号(此服务会监听这个端品口);

 * 准备一个数据报包对象DatagramPacket,用于封装接收到的数据;

 * 通过socket服务对象的receive(DatagramPacket)方法,接收数据;

 * 处理接收回来的数据(解析DatagramPacket);

 * 关闭资源;

客户端:

* 建立一个UDP的socket服务(可不明确端口号,系统自动配置);

 * 准备数据,并将要发送的数据封装到数据包中(DatagramPacket);

 * 通过socket服务的send(DatagramPacket)方法将数据包发送出去;

 * 关闭资源;

演示代码(简的网络聊天程序):

***********************************************************************
//用户一:
public class UdpRece {
	public static void main(String[] args) throws IOException {
		new Thread(new UdpRece1()).start();//接收端
		new Thread(new UdpSend1()).start();//发送端		
	}
}

// 接收信息程序(9080端口)
class UdpRece1 implements Runnable {
	private DatagramSocket ds;
	UdpRece1() {
		try {
			this.ds = new DatagramSocket(9080);
		} catch (SocketException e) {
		}
	}
	@Override
	public void run() {
		System.out.println("用户1接收端开启");
		String data;// 接收对方接发过来的信息
		do {
			byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(
buf, buf.length);
			try {
				ds.receive(dp);
			} catch (IOException e) {
			}

			String ip = dp.getAddress().getHostAddress();
			int port = dp.getPort();
			data = new String(
dp.getData(), 0, dp.getData().length);

			if (data.equals("close")) {
				break;
			}
			System.out.println("---------
本次接收到的数据为:-----------");
			System.out.println(ip);
			System.out.println(port);
			System.out.println(data);
			System.out.println("---------------
------------------");
		} while (true);
		ds.close();
		return;
	}
}
//发送信息程序
class UdpSend1 implements Runnable {
	private DatagramSocket da;
	UdpSend1() {
		try {
			this.da = new DatagramSocket();
		} catch (SocketException e) {
		}
	}
	@Override
	public void run() {
		System.out.println("用户1发送端开启");
		do {
			System.out.println("请输入你要发送的内
容(输入'close'退出!):");
			Scanner scanner = new Scanner(System.in);
			String ss = scanner.next();
			if (ss.equals("close")) {
				break;
			}
			// 准备数据,并将数据、要发送的地地址,对方端口号
三个信息封装到数据报包对象中
			byte[] data = ss.getBytes();
			DatagramPacket dp = null;
			try {
			dp = new DatagramPacket(data, data.length,
						InetAddress.getByName("192.168.1.100"), 9081);
			} catch (UnknownHostException e) {
				e.printStackTrace();
			}
			// 将数据报包发出去
			try {
				da.send(dp);
			} catch (IOException e) {
			}
		} while (true);
		da.close();
		return;
	}

}
***********************************************************************
//用户二
public class UdpSend {
	public static void main(String[] args) throws IOException {
	new Thread(new UdpRece2()).start();//接收端
	new Thread(new UdpSend2()).start();//发送端
	}
}

//接收信息程序(9080端口)
class UdpRece2 implements Runnable {
	private DatagramSocket ds;

	UdpRece2() {
		try {
			this.ds = new DatagramSocket(9081);
		} catch (SocketException e) {
		}

	}

	@Override
	public void run() {

		System.out.println("用户2接收端开启");

		String data;// 接收对方接发过来的信息
		do {
			byte[] buf = new byte[1024];
	DatagramPacket dp = new DatagramPacket(
buf, buf.length);
			try {
				ds.receive(dp);
			} catch (IOException e) {
			}

			String ip = dp.getAddress().getHostAddress();
			int port = dp.getPort();
			data = new String(dp.getData(), 
0, dp.getData().length);

			if (data.equals("close")) {
				break;
			}

			System.out.println("---------本次接收到的数据为:---
--------");
			System.out.println(ip);
			System.out.println(port);
			System.out.println(data);
			System.out.println("----------------------------
-----");

		} while (true);
		ds.close();
		return;
	}
}
//发送信息程序:
class UdpSend2 implements Runnable {
	private DatagramSocket da;

	UdpSend2() {

		try {
			this.da = new DatagramSocket();
		} catch (SocketException e) {
		}
	}
	@Override
	public void run() {
		System.out.println("用户2发送端开启");
		do {
			System.out.println("请输入你要发送的内容(输
入'close'退出!):");
			Scanner scanner = new Scanner(System.in);

			String ss = scanner.next();
			if (ss.equals("close")) {
				break;
			}

			// 准备数据,并将数据、要发送的地地址,对方端口号三
个信息封装到数据报包对象中
			byte[] data = ss.getBytes();
			DatagramPacket dp = null;
			try {
			dp = new DatagramPacket(data, data.length,
				InetAddress.getByName("192.168.1.100"), 9080);
			} catch (UnknownHostException e) {
				e.printStackTrace();
			}

			// 将数据报包发出去
			try {
				da.send(dp);
			} catch (IOException e) {
			}
		} while (true);

		da.close();
		return;
	}
}
***********************************************************************

2.TCP通讯规则下的编程

基本步骤:

服务端:

*  1.创建TCP的ServerSocket服务(socket),需要指定监听的端口号;

*  2.通过ServerSocket的accept()方法得到与客户端的socket对象;

 * 3. 通过客户端的socket对象得到连接的输入流InputStream;

*  4.从输入流程中读取客户端发送过来的数据,通过socket对象解析对方发送相关的信息。

*  5.关闭资源;

客户端:

*  1.创建TCP的socket服务(socket),需要对方指定IP地址及端口号;

 * 2.拿到socket输出流OutputStream;

 * 3.通过这个流程将数据写出去;

 * 4.关闭资源;

演示代码:

***********************************************************************
//服务端(接收端)
public class Tcp_Rece {
	public static void main(String[] args) throws IOException {
		//创建ServerSocket服务
		ServerSocket serverSocket = new ServerSocket(10086);
		//监听端口,得到客户端的Socket对象
		Socket socket = serverSocket.accept();
		//从客户端的Socket对象中得到输入流
		InputStream in = socket.getInputStream();
		//从输入流是读取数据
		int len;
		byte[] bfu = new byte[1024];
		while ((len = in.read(bfu)) != -1) {
			System.out.println(new String(bfu, 0, len));
		}
		System.out.println("接收成功");
		//关闭资源
		socket.close();
		serverSocket.close();
	}
}
//发送端(客户端)
public class Tcp_Send {
	public static void main(String[] args) throws UnknownHostException,
			IOException {
		// 建议服务
		Socket socket = new Socket("192.168.1.100", 10086);
		// 得到输出流OutputStream
		OutputStream outs = socket.getOutputStream();
		// 输出数据
		outs.write("Tcp测试数据".getBytes());
		System.out.println("发送成功");
		//关闭资源
		socket.close();
	}
}
***********************************************************************
以上代码可以利用多线程的技术进行重构,实现简单的即时聊天程序,由于实现思路与以述UDP的聊天程序基本一致,代码略去。
小案例:利用TCP协议编写一个写小转大写的客户端/服务端的网络程序,具体代码如下:
***********************************************************************
/*
 * 服务端
 * 
 * */
public class Service {
	public static void main(String[] args) throws IOException {
		System.out.println("服务端开启");
		// 创建一个ServerSocket的服务端,监听一个端口
		ServerSocket ss = new ServerSocket(10086);
		// 得到客户端的Socket
		Socket sk = ss.accept();
		// 从客户端的Socket中得到输入流InputSource
		InputStream in = sk.getInputStream();
		// 从客户端的Socket中得到输出流OutputStream
		OutputStream out = sk.getOutputStream();
		while (true) {
			// 从InputSource中得到客户端发过来的数据
			int len;
			byte[] bfu = new byte[1024];
			while ((len = in.read(bfu)) != -1) {
				// 如果客输入的是close,则退出
				if (bfu.toString().equals("close")) {
					ss.close();
					break;
				}
				// 将数据转化为大写的
byte[] data = new String(bfu, 0, len).toUpperCase().getBytes();
				// 通过OutputStream将数据输出给客户端
out.write(new String("转换
结果为:").getBytes());
				out.write(data, 0, data.length);
				System.out.println("转换结果为:" +
 new String(data, 0, data.length));
			}
		}
		// 关闭资源(实际情况下服务端是一直处于开启状态的)
		// sk.close();
	}
}

/*
 * 客户端
 * 
 * */
public class Consumer {
	public static void main(String[] args) throws IOException {
		System.out.println("客户端开启");
		// 创建Socket的服务端
		Socket sk = new Socket("192.168.1.100", 10086);
		// 从服务中得到输出流OutputStream
		OutputStream out = sk.getOutputStream();
		// 从服务中得到输入流InputSource
		InputStream in = sk.getInputStream();
		// 从控制台输入数据
		Scanner scanner = new Scanner(System.in);
		while (true) {
			System.out.println("输入你要转换的字母:");
			String data = scanner.next();
			// 如果输入的是close就退出
			if (data.equals("close")) {
				break;
			}
			// 用输出流将数据写到服务端
			out.write(data.getBytes());
			// 从输入流中得到服务端的响应信息
			byte[] bfu = new byte[1024];
			in.read(bfu);
			// 将信息显示在控制台上
			System.out.println(new String(bfu, 0, bfu.length));
			System.out.println("-----接收成功------");
		}
		sk.close();
	}
}
***********************************************************************














  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
城市应急指挥系统是智慧城市建设的重要组成部分,旨在提高城市对突发事件的预防和处置能力。系统背景源于自然灾害和事故灾难频发,如汶川地震和日本大地震等,这些事件造成了巨大的人员伤亡和财产损失。随着城市化进程的加快,应急信息化建设面临信息资源分散、管理标准不统一等问题,需要通过统筹管理和技术创新来解决。 系统的设计思路是通过先进的技术手段,如物联网、射频识别、卫星定位等,构建一个具有强大信息感知和通信能力的网络和平台。这将促进不同部门和层次之间的信息共享、交流和整合,提高城市资源的利用效率,满足城市对各种信息的获取和使用需求。在“十二五”期间,应急信息化工作将依托这些技术,实现动态监控、风险管理、预警以及统一指挥调度。 应急指挥系统的建设目标是实现快速有效的应对各种突发事件,保障人民生命财产安全,减少社会危害和经济损失。系统将包括预测预警、模拟演练、辅助决策、态势分析等功能,以及应急值守、预案管理、GIS应用等基本应用。此外,还包括支撑平台的建设,如接警中心、视频会议、统一通信等基础设施。 系统的实施将涉及到应急网络建设、应急指挥、视频监控、卫星通信等多个方面。通过高度集成的系统,建立统一的信息接收和处理平台,实现多渠道接入和融合指挥调度。此外,还包括应急指挥中心基础平台建设、固定和移动应急指挥通信系统建设,以及应急队伍建设,确保能够迅速响应并有效处置各类突发事件。 项目的意义在于,它不仅是提升灾害监测预报水平和预警能力的重要科技支撑,也是实现预防和减轻重大灾害和事故损失的关键。通过实施城市应急指挥系统,可以加强社会管理和公共服务,构建和谐社会,为打造平安城市提供坚实的基础
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值