【黑马程序员】java中----------网络编程一

---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------

一、学习java中的网络编程前期

1.学习OSI模型和TCP/IP网络参考模型


以下为TCP/IP参考模型


1.我们开发人员需要掌握几个重要的

应用层,为模型的最顶层,为用户提供所需要的各种服务,例如:FTP,Telnet,DNS,

SMTP,HTTP服务

传输层:提供端到端的通信功能,保证数据的顺序传送及数据的完整性。该层提供了:

传输控制协议(TCP)和(UDP)

TCP协议提供的是安全可靠的、面向链接的数据传送服务;而UDP协议提供的是不可靠的、面向无连接的数据传送服务


网络层:主要解决主机到主机的通信问题。它包含的协议涉及数据包在整个网络上的逻辑传输。

注重从新赋予主机一个IP 地址来完成对主机的寻找,它负责数据包在多种网络中的路由。

该层有4个主要协议:网际协议(IP)、地址解析协议(IGMP)、妇联网组管理协议(IGMP)和互联网控制报文协议(ICMP)


2.网络传输的3个要素:

a.传输协议(TCP/UDP)

UDP特点:

面向无连接,发送数据不能超过64K、因为是无连接,是不可靠协议、无需接力连接,传输速度快

可用于视频会议等。

TCP特点:

面向连接的、通信是安全可靠的、速度慢、可以用于大数据传输、通过3次握手建立连接

可以用于下载数据。

b.IP地址不易记忆,可以用主机名表示,两者存在映射关系。

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


c. 端口号:用于标识进程的逻辑地址,应用程序和系统服务的身份证号一样,如果一台计算机中的应用程序要给另一个主机的应用程序

发送数据,形成连接,需要这个端口号进行标识,。一个应用程序或进程对应一个端口,

有效的端口:0——65535,系统使用的保留端口号:0——1024.

端口号只能用数字表示,也可以叫逻辑端口


二、网络通信步骤

1.找到IP,寻址并进行连接

2.通过TCP/IP传输协议将数据发送到连接的主机指定的端口的应用程序或服务


三、数据传输和接收数据包拆包过程

就比如是上图的参考模型,数据从应用层开始封包,到底层物理层通过传输到指定主机指定的端口的应用程序

进行逐层拆包还原数据。


四、java中描述IP的类和对象InetAddress


在java中,有一个描述IP的类InetAddress类,该类继承object类并且

实现了Serializable接口,实现此接口的对象可以被序列化。


InetAddress类没有构造方法,我们可以通过类中的方法获取到本类对象:

1.  通过方法getByName(string host)返回InetAddress对象


2.我们也可以通过本来对象中的方法getLocalHost()返回本地主机IP地址对象的InetAddress


InetAddress对象中的常用方法:

stringgetHostName()获取此IP地址对象的主机名

stringgetHostAddress()返回此对象中的 IP地址的字符串

stringgetCanonicalHostName()返回此对象的完整域名


练习代码:

import java.net.*;

class IPDemo
{
	public static void main(String[] args)throws  Exception
	{	
		//异常:UnknownHostException - 如果找不到 host 的任何 IP 地址。
		InetAddress  ad=InetAddress.getLocalHost();
		String ip=ad.getHostAddress();
		System.out.println("IP地址:"+ip);
		
		InetAddress  ia=InetAddress.getByName("www.baidu.com");
		
		//System.out.println(ia.getHostAddress());
		System.out.println(ia.getHostName());
	}
}
打印结果;

ip地址:182.99.189.122

www.baidu.com


五、UDP传输协议的网络编程中

java提供了3个主要的类:DataGramSocket、DataGramPacket、InetAddress


1、DataGramSocket:

1.       此类表示用来发送和接收数据报包的套接字。数据报套接字是包投递服务的发送或接收点,类似生活中邮局、港口一样。区分不同应用程序进程间的网络通信和连接,主要有3个参数:通信的目的IP地址、使用的传输层协议(TCP或UDP)和使用的端口号。Socket原意是“插座”。通过将这3个参数结合起来,与一个“插座”Socket绑定,应用层就可以和传输层通过套接字接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。

2.      通信两端都要创建Socket,才能建立数据包来往的服务。

3.      网络通信其实就是Socket之间的通信,数据在两个Socket之间通过IO传输。

2、DataGramPacket将数据封为数据包

1. 建发送服务Soket(使用DatagramSocket创建)
2. 提供数据,发送的数据必须是字节,如果不是先专为字节数据,用byte数组缓存,并创建数据发送包(DatagramPacket)去封装byte数组中的数据和指定发 地点和端口。
3. 通过Socket服务的send(dp)方法将数据发送出去
4. 关闭资源

接收端也一样要将受到的数据封包

1. 建立接收服务Soket(使用DatagramSocket创建)
2. 接收的数据都是字节数据,创建byte缓冲数组,并创建接收数据包(DatagramPacket)去封装管理、接收到数据。
3. 通过Socket服务的receive(dp)方法将数据接收到字节数组中。
4. 关闭资源

5.为什么数据包要封装在DatagramPacket对象中?在使用接收发送数据的方法中,仍会传入一个DatagramPacket类型的对象参数,这是因为收到的数据太多,需要解析,通过将数据封装成对象,易于解析,所以需要传入参数,便于管理。

练习代码:

import java.net.*;
import java.io.*;
//发送端
class UdpSend2{
	public static void main(String[] args)throws IOException
	{
		DatagramSocket ds=new DatagramSocket();//创建socket流
		
		BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
		
		String line=null;
		
		while((line=bufr.readLine())!=null)
		{
			if("886".equals(line))
				break;
			byte[] buf=line.getBytes();//将读取的一行数据转换成字节数组
			//将字节数组封包
			DatagramPacket dp=new DatagramPacket(buf,buf.length,InetAddress.getByName(""),10001);
			
			ds.send(dp);//发送
		}
		ds.close();//关流
	}
	
}

//接收端
import java.net.*;
import java.io.*;
class UdpRece2{
	public static void main(String[] args)throws IOException
	{
	DatagramSocket ds=new DatagramSocket(10000);//创建socket流
	
		while(true)
		{
			
			byte[] buf=new byte[1024];
			
			DatagramPacket dp=new DatagramPacket(buf,buf.length);
			
			ds.receive(dp); //接收数据,并且将数据封装进DataGramPacket包中
			
			String ip=dp.getAddress().getHostAddress();
			
			String data=new String(dp.getData(),0,dp.getLength());//将数组中的数据转换成字符串
			
			System.out.println(ip+"============="+data);
		}
	}
}

练习代码:简单的UDP协议的聊天程序

提供线程技术,一条线程控制接收数据,一条数据控制发送数据

/*编写一个聊天程序
有收数据的部分,和发数据的部分
这两部分需要同步执行
一个线程控制接收,一个线程控制发送*/

import java.io.*;
import java.net.*;
//发送端
class Send implements Runnable{
	private DatagramSocket ds;
	//通过构造函数接收socket流
	public Send(DatagramSocket ds)
	{
		this.ds=ds;
	}
	public void run()
	{
		try
		{	//读取键盘录入
			BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
			String line=null;
			while((line=bufr.readLine())!=null)
			{
				if("886".equals(line))
					break;
				byte[] buf=line.getBytes();
				//数据封包															
				DatagramPacket dp =new DatagramPacket(buf,buf.length,InetAddress.getByName("182.99.189.122"),10000);
				
				ds.send(dp);//发送
				
				
				
			}
		}
		catch(Exception e)
		{
			throw new RuntimeException("发送端失败");
		}
		
		ds.colse();
		
	}


}
//接收端
class Rece implements Runnable{
	//定义变量
	private DatagramSocket ds;
	//通过构造函数接收socket流
	public Rece(DatagramSocket ds)
	{
		this.ds=ds;
	}
	public void run()
	{	
		try
		{
			while(true)//循环接收读取的数据
			{
				byte[] buf=new byte[1024];
				//接收的数据封包
				DatagramPacket dp=new DatagramPacket(buf,buf.length);
				ds.receive(dp);
				
				String ip=dp.getAddress().getHostAddress();
				
				String data=new String(dp.getData(),0,dp.getLength());
				
				System.out.println(ip+"----"+data);
			}
		}
		catch(Exception e)
		{
			throw new RuntimeException("接收端失败");
		}
		
		
	
	
	}
}
//程序入口
class ChatDemo{
	public static void main(String[] args)throws IOException
	{
		DatagramSocket sendSocket=new DatagramSocket();
		DatagramSocket receSocket= new DatagramSocket(10000);
		new Thread(new Send(sendSocket)).start();
		new Thread(new Rece(receSocket)).start();
	}
}





















---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值