----------------------- android培训、java培训、java学习型技术博客、期待与您交流! ----------------------
网络编程:
1.网络模型
OSI参考模型
TCP/IP参考模型
2.网络通讯要素
IP地址
端口号
传输协议
2.1 java.net.InetAddress
Ip:网络中设备的标识
www.baidu.com-->DNS域名解析服务器,将域名转成IP地址
本地回环地址:127.0.0.1 主机名:localhost
描述IP地址对象的类 java.net.InetAddress
IntAddress类中常用的方法
InetAddress ia = InetAddress .getByName(“www.baidu.com”);//返回指定主机IP地址
System.out.println("address:"+ia.getHostAddress());//返回 IP 地址字符串(以文本表现形式)
System.out.println("name:"+ia.getHostName());//获取此 IP 地址的主机名
InetAddress ia = InetAddress.getLocalHost();//返回本地主机包含IP
2.2端口号
用于标识进程的逻辑地址,不同进程的标识
有效端口:0~65535,其中0~1024系统使用或保留端口。
2.3传输协议
UDP特点:
将数据及源和目的封装成数据包中,不需要建立连接
每个数据报的大小在限制在64k内
因无连接,是不可靠协议
不需要建立连接,速度快
例子:一般IM软件QQ,FQ飞秋,视频会议,桌面共享是UDP传输的
TCP特点:
建立连接,形成传输数据的通道。
在连接中进行大数据量传输
通过三次握手完成连接,是可靠协议
必须建立连接,效率会稍低
2.4 Socket
Socket就是为网络服务提供的一种机制。
通信的两端都有Socket。
网络通信其实就是Socket间的通信。
数据在两个Socket间通过IO传输。
UDP
|-- DatagramPacket 数据包,发送封装包,接收要拆包
|-- 构造
|-- getLength 获取字节数组的有效个数
|-- getPort 发送端的端口号
|-- DatagramSocket 通信端
|-- 构造
|-- send(数据包) 发送数据的
|-- receive(数据包)接收数据
练习:发送,接受数据
/*
* UDP的发送端
* 实现步骤:
1. 找快递 Socket服务对象,描述类 java.net.DatagramSocket
DatagramSocket()
2. 将你要发送的数据,封装成数据包 对象,描述类 java.net.DatagramPacket
DatagramPacket(byte[] buf, int length, InetAddress address, int port)
构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。
3. 快递直接发送 DatagramSocket void send(DatagramPacket p)
从此套接字发送数据报包。
4. 关门,关闭资源
*/
import java.net.*;
public class UDPSend {
public static void main(String[] args)throws Exception {
//建立Socket服务对象
DatagramSocket ds = new DatagramSocket(9000);
//封装数据包
byte[] buf = "你好UDP".getBytes();
DatagramPacket dp =
new DatagramPacket
(buf,buf.length,InetAddress.getByName("192.168.3.100"),10000);
//使用Socket服务对象发送数据 send方法
ds.send(dp);
//关闭资源
ds.close();
}
}
/*
* UDP接收端
* 实现步骤:
* 1. 建立Socket服务
* 2. 定义数据包并接收
* 3. 通过数据包对象的特有功能拆包
* 4. 关闭资源
*/
import java.net.*;
public class UDPReceive {
public static void main(String[] args)throws Exception {
//建立Socket服务
// DatagramSocket(int port) 端口号
//java.net.BindException异常 端口被占异常
DatagramSocket ds = new DatagramSocket(10000);
//DatagramPacket(byte[] buf, int length)
// 构造 DatagramPacket,用来接收长度为 length 的数据包。
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, buf.length);
//接收包
ds.receive(dp);//线程阻塞效果
//通过数据包的方法获取其中的数据。
String ip = dp.getAddress().getHostAddress();//InetAddress getAddress() 返回某台机器的 IP 地址,此数据包将要发往该机器或者是从该机器接收到的。
String data = newString(dp.getData( ),0,dp.getLength( )); // int getLength() 接收到的字节数组中的有效长度
int port = dp.getPort(); //int getPort() 获取发送方的端口号
System.out.println(ip+"::"+data+"::"+port);
//关闭资源
ds.close();
}
}
192.168.1.255 中的255 为一个段号中的广播,可以给这个段的所有IP发送数据
练习:UDP简单聊天的功能
import java.net.*;
import java.io.*;
// UDP的发送端:键盘录入,录一行,发一行
class UdpSend2 {
public static void main(String[] args)throws Exception{
DatagramSocket ds = newDatagramSocket();
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("192.168.1.255"),10001);
ds.send(dp);
}
ds.close();
}
}
// 键盘录入的接收 (没变)
class UdpRece2 {
public static void main(String[] args)throws Exception {
DatagramSocket ds = newDatagramSocket(10001);
while(true){
byte[] buf = newbyte[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);
}
}
}
练习:UDP编写一个聊天程序 多线程(*******)
/*
编写一个聊天程序。 多线程实现单一窗口的收与发
有收数据的部分,和发数据的部分。 这两部分需要同时执行。
那就需要用到多线程技术。 一个线程控制收,一个线程控制发。
因为收和发动作是不一致的,所以要定义两个run方法。
而且这两个方法要封装到不同的类中。
*/
import java.io.*;
import java.net.*;
class Send implements Runnable {
private DatagramSocket ds;
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) {
byte[] buf= line.getBytes();
DatagramPacketdp = newDatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.255"),10002);
ds.send(dp);
if("886".equals(line))
break;
}
}
catch (Exception e){
throw newRuntimeException("发送端失败");
}
}
}
class Rece implements Runnable {
private DatagramSocket ds;
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());
if("886".equals(data)) {
System.out.println(ip+"....离开聊天室");
break;
}
System.out.println(ip+":"+data);
}
}
catch (Exception e) {
throw new RuntimeException("接收端失败");
}
}
}
class ChatDemo {
public static void main(String[] args)throws Exception {
DatagramSocket sendSocket =new DatagramSocket();
DatagramSocket receSocket =new DatagramSocket(10002);
new Thread(newSend(sendSocket)).start();
new Thread(newRece(receSocket)).start();
}
}
----------------------- android培训、java培训、java学习型技术博客、期待与您交流! ----------------------