---------------------- <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>、期待与您交流! ----------------------