黑马程序员--网络编程(一)

----------------- android培训java培训、期待与您交流!-----------------




网络编程

网络编程就是两个或多个设备之间的数据交换,其实更具体的说,网络编程就是两个或多个程序之间的数据交换,和普通的单机程序相比,网络程序最大的不同就是需要交换数据的程序运行在不同的计算机上,这样就造成了数据交换的复杂。

网络传输3要素
1   找到对方IP地址
2   数据要发送到指定的应用程序,程序需要标记,而这些用来标识程序的数字称为端口号(逻辑端口)
3   需要遵循通讯规则,这规则称为协议。不同协议之间不能进行通讯。国际组织定义了通用协议TCP/IP。
IP地址: 网络中设备的标识,如127。0。0。1。因为不易记忆,可用主机名。
端口号:用于标识进程的逻辑地址,不同进程的标识。
      有效端口:0~65535,其中0~1024系统使用或保留端口。
传输协议:就是通讯的规则,常见协议:TCP,UDP。

UDP--
将数据及源和目的封装成数据包中,不需要建立连接
每个数据报的大小在限制在64k内
因无连接,是不可靠协议。不需要建立连接,速度快
如:聊天,凌波多媒体,桌面共享...
TCP--
建立连接,形成传输数据的通道。
在连接中进行大数据量传输
通过三次握手完成连接,是可靠协议
必须建立连接,效率会稍低
如:网络游戏,迅雷下载,大多数应用...


网络编程中的两种程序就分别是客户端和服务器端。
C/S结构:
例如QQ程序,每个QQ用户安装的都是QQ客户端程序,而QQ服务器端程序则运行在腾讯公司的机房中,
为大量的QQ用户提供服务。这种网络编程的结构被称作客户端/服务器结构,也叫做Client/Server结构,简称C/S结构。
B/S结构:
其实在运行很多程序时,没有必要使用专用的客户端,而需要使用通用的客户端,
例如浏览器,使用浏览器作为客户端的结构被称作浏览器/服务器结构,也叫做Browser/Server结构,简称为B/S结构。

socket
Socket就是为网络服务提供的一种机制。
通信的两端都有Socket。
网络通信其实就是Socket间的通信。
数据在两个Socket间通过IO传输。
Socket编程重要的是记住流程。
下面来看看访问网络和ip的一些基本操作
public static void IPd(){
		try {
			InetAddress addr =InetAddress.getLocalHost();	//得到自己主机名和ip地址
			System.out.println(addr.toString());
			InetAddress netaddr =InetAddress.getByName("www.baidu.com");  //获取访问网址的信息
			System.out.println("address---"+netaddr.getHostAddress());    //获取ip
			System.out.println("name---"+netaddr.getHostName());  //获取主机名
			InetAddress[] ipa =InetAddress.getAllByName("www.baidu.com");   //返回获取网址ip列表
			System.out.println(""+ipa);
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
	}

下面来看看基于UDP协议的编程
首先是客户端的实现代码
class  UdpClient
{
	public static void main(String[] args) 
	{
		udpSend();
	}


	/**
	 * 通过UDP传输方式,将一段文字数据发送出去
	 * 步骤
	 * 1  建立UDP 的socket服务
	 * 2  提供数据,并将数据分钟到数据包中
	 * 3  通过socket服务的发送功能,将数据包发送出去
	 * 4  关闭资源
	 */
	 public static void udpSend(){ 
		 try {
			 //1   创建udp服务,通过DatagramSocket对象
			DatagramSocket ds =new DatagramSocket();
			//2   确定数据,并分装成数据包,指定要发送的服务器ip,和端口号
			byte [] bt = "用来发送的数据1".getBytes();
			DatagramPacket dPacket =
					new DatagramPacket(bt, bt.length, InetAddress.getByName("192.168.42.48"),5345);  
			//3  通过socket服务,send()方法将数据包发送出去
			ds.send(dPacket);
			ds.close();
		 }catch (Exception e) {
			e.printStackTrace();
		}
	 }
}
然后是服务端的代码
class  UdpServer
{ 
	public static void main(String[] args) 
	{
		udpReceive();
	}


	/**
	  * 定义一个程序,用于接收udp协议传输的数据并处理
	  * 步骤
	  * 1   定义udp 的socket服务--  需要给这个接收网络应用程序定义端口号,
	  * 			方便明确哪些数据过来该应用程序可以处理
	  * 2   定义一个数据包用来存储接收到的字节数据
	  * 3   通过socket我服的receive方法将接收到的数据存入到已经定义的数据包中
	  * 4   通过数据包对象的特有功能,将这些不同的数据取出,打印在控制台上
	  * 5   关闭资源
	  */
	 public static void udpReceive(){
		 try {
			 //1  创建udp socket服务,
			DatagramSocket dSocket =new DatagramSocket(5345);
			//2  定义数据包,字节数组,用于存储数据
			byte [] buf =new byte[1024];
			DatagramPacket dPacket =new DatagramPacket(buf, buf.length);
			//3  通过socket服务的receive方法将接受到的数据存放在数据包中
			dSocket.receive(dPacket);
			//4  通过数据包的方法获取其中数据
			String  ip = dPacket.getAddress().getHostAddress();
			String data = new String(dPacket.getData(),0,dPacket.getLength());
			int  port = dPacket.getPort();
			System.out.println(ip+"   "+data+"   "+port);
			dSocket.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	 }
}
演示时先要开启服务端,在启动客户端就能接收到数据 了。这就是一个基于UDP协议的简单列子,可以看到,使用udp协议还是蛮容易的。
接下来看看使用TCP协议的程序通讯
TCP--
客户端Socket
客户端需要明确服务器的ip地址以及端口,这样才可以去试着建立连接,
如果连接失败,会出现异常。连接成功,说明客户端与服务端建立了通道,
那么通过IO流就可以进行数据的传输,而Socket对象已经提供了输入流和输出流对象,
通过getInputStream(),getOutputStream()获取即可。
与服务端通讯结束后,关闭Socket。
服务器端ServerSocket
服务端需要明确它要处理的数据是从哪个端口进入的。
当有客户端访问时,要明确是哪个客户端,可通过accept()获取已连接的客户端对象,
并通过该对象与客户端通过IO流进行数据传输。
当该客户端访问结束,关闭该客户端。

下面是具体代码--通过一个上传图片的小程序
class TcpClient 
{
	public static void main(String[] args) 
	{
		ImgClient();
	}


	/**
	 * 客户端
	 * 1  创建socket服务,指定服务器和端口号
	 * 2  读取本地图片数据
	 * 3  通过socket输出流将数据发送给服务器
	 * 4  读取从服务器反馈的数据
	 * 5  关闭客户端
	 */
	public static void ImgClient(){
		Socket sk =null;
		BufferedInputStream bis,bis2=null;
		try {
			sk = new Socket("192.168.42.48",10200);
			//指定读取图片的出入流
			bis = new BufferedInputStream(new FileInputStream("ic.png"));
			byte [] buf =new byte [1024];
			int num =0;
			//通过Socket的getOutputStream()获取一个Socket的输出流
			BufferedOutputStream bos = new BufferedOutputStream(sk.getOutputStream());
			while ((num = bis.read(buf))!=-1) {
				//将数据写到服务器中
				bos.write(buf,0,num);
				bos.flush();
			}
			sk.shutdownOutput();//告诉服务器数据已写入,是个结束标志
			//获取Socket的getInputStream()输入流,
			bis2 = new BufferedInputStream(sk.getInputStream());
			byte [] bt =new byte[1024];
			int result =0;
			while (( result=bis2.read(bt))!=-1) {
				//接受服务器反馈的数据,并打印在控制台
				System.out.println(new String(bt,0,result));
			}	
			//关闭资源
			bis.close();
			sk.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
在看服务器端
class  TcpServer
{
	public static void main(String[] args) 
	{
		ImgServer();
	}


	/**
	 * 服务器
	 * 1  创建serverSocket服务,指定监听端口
	 * 2  通过accept()方法获取连接过来的客户端,无就等待
	 * 3  通过socket的getInputStream()获取客户端的图片数据
	 * 4  将数据写到到服务器中,
	 * 5  写入完毕后发送数据到客户端中,说明客户端图片上传成功
	 * 6  关闭资源
	 */
	public static void ImgServer(){
		ServerSocket  ss =null;
		BufferedInputStream bis =null;
		BufferedOutputStream bos,bos2=null;
		try {
			ss = new ServerSocket(10200);	// 创建serverSocket服务,指定监听端口
			Socket socket = ss.accept();    //通过accept()方法获取连接过来的客户端,无就等待。是个阻塞方法
			//打印连接上的客户端ip
			System.out.println(socket.getLocalAddress().getHostAddress()+"------lianjie-----");
			//获取流对象
			bis = new BufferedInputStream(socket.getInputStream());
			bos= new BufferedOutputStream(new FileOutputStream("copyByIc.png"));
			byte [] buf  = new byte[1024];
			int num ;
			while ((num = bis.read(buf))!=-1) {
				//读取客户端的图片数据,并写入到服务器中
				bos.write(buf, 0, num);
				bos.flush();
			}
			//获取getOutputStream()输出流反馈信息给客户端
			bos2 = new  BufferedOutputStream(socket.getOutputStream());
			bos2.write("-----图片上传成功----".getBytes());
			//关闭资源
			bos2.close();
			socket.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
通过这2个例子大家应该都知道了udp,tcp通讯的方式。在编程时,要了解需求,知道这通讯的主要流程那就容易多了。网络编程一般都是有io技术结合的。









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值