----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------
网络模型:OSI参考模型、 TCP/IP参考模型
网络通讯要素:IP地址、端口号、传输协议
OSI:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。
TCP/IP:主机层至网络层、网络层、传输层、应用层。
数据链路层:对从物理层接受的数据进行MAC(网卡地址)地址的封装和解封装
网络层:进行IP地址的封装。
传输层:定义了一些传输数据的协议和端口号
会话层:传输端口和接受端口,访问请求和接受。建立数据传输通道
IP地址:网络中设备的标识
本地回环地址:127.0.0.1是主机网卡内置好默认的IP地址。用来标识本地的。
主机名:localhost 和IP地址相对应
由于ip地址有四段,不易记忆,可用主机名来访问。
IP地址对象的获取
java.net.InetAddress
---java.net.Inet4Address
将IP地址封装成对象
通过InetAddress类中的静态方法getLocalHost()来获取本地ip地址对象。该方法返回的是ip地址对象。
通过InetAddress类中的静态方法getByName("指定的主机名或者ip地址字符串")来获取指定主机的ip地址对象。如www.sina.com
Ip地址对象可调用getHostAddress()来获取ip地址的字符串对象
调用getHostName()来获取ip地址对应的主机名字符串对象。
浏览器 输入www.sina.com是主机名,它回去查DNS域名解析服务器得到主机名对应的ip地址,然后再通过ip访问到新浪的主机。
在系统中本身就有一个ip和主机名的映射关系表hosts(system32-drivers-etc-hosts)
端口号:就是用于表示应用程序的数字。逻辑端口
用于标识进程的逻辑地址,不同进程的标识。
有效端口0-65535,其中0-1024系统所用或保留端口。
Socket是为网络服务提供的一种机制。通信两端都有Socket。
网络通信其实就是Socket间的通信。
数据在两个Socket间通信通过io流传输
Socket网络服务的端点,插座。
UDP发送和接受代码演示:
public static void main(String[] args) throws IOException {
需求:通过udp协议发送一段数据给指定主机。
System.out.println("udp的发送端开启");
//1,既然要进行udp协议的网络通信,当然要建立udp的socket服务.
DatagramSocket ds = new DatagramSocket(10000);绑定一个端口号10000.
//2,确定发送的具体的数据。
String str = "hi,udp 哥们来了!";
byte[] buf = str.getBytes();
//3,创建数据包对象,因为udp协议是需要将数据封装到指定的数据包中。
DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.100"),10000);参数列表里分别是字节数组,数组长度,ip地址,端口号。
//4,使用udpsocket服务的send方法。将数据包发出。
ds.send(dp);
//5,关闭资源。
ds.close();
}
接收端
需求:接收到发过来的数据,并将数据中的ip 地址和 端口以及数据内容都打印在显示器。
System.out.println("接收端开启.......");
//1,创建udp socket服务对象。绑定一个指定的端口。给该应用程序分配一个数据标示。也可以称之为监听一个端口。
DatagramSocket ds = new DatagramSocket(10000);
//2,创建数据包,用于存储接收到的数据,并用数据包对象的方法对数据包中的内容进行解析。
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
//3,使用socket对象的receive方法将接收到的数据都存储到数据包的对象中。
ds.receive(dp);//阻塞式方法。
//4,既然数据已经存储到数据包中,
// 直接用数据包的方法对这些数据进行解析。
//获取ip。
String ip = dp.getAddress().getHostAddress();
//获取port 端口号
int port = dp.getPort();
//获取数据内容。
byte[] data = dp.getData();
String text = new String(data,0,dp.getLength());
System.out.println(ip+":"+port+"::"+text);
//5,关闭资源。
ds.close();
Udp 的发和收是互不影响,多线程。
建立udp的socket服务 :DatagramSocket
创建用于发送和接受的数据包:DatagramPacket
发送数据包用DatagramSocket类中的send(数据包);
接受数据包用receive(数据包)方法;
完毕后 ,需关闭资源。
Udp的练习:群聊
群聊程序,
收发同时运行,需要一个线程负责收数据,一个线程负责发数据。
定义两个线程任务
//定义发送任务。
class Send implements Runnable{
private DatagramSocket ds ;
public Send(DatagramSocket ds) {
super();
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();
DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.255"),10001);
ds.send(dp);
if("over".equals(line))
break;
}
ds.close();
}
catch(IOException e){
}
}
}
//定义接收任务。
class Rece implements Runnable{
private DatagramSocket ds ;
public Rece(DatagramSocket ds) {
super();
this.ds = ds;
}
public void run(){
try {
byte[] buf = new byte[1024];
while(true){
DatagramPacket dp = new DatagramPacket(buf,buf.length);
ds.receive(dp);
String ip = dp.getAddress().getHostAddress();
String text = new String(dp.getData(),0,dp.getLength());
System.out.println(ip+":"+text);
if("over".equals(text)){
System.out.println(ip+".....离开聊天室");
}
}
} catch (Exception e) {
// TODO: handle exception
}
}
两个任务类定义完后,就开始创建线程。
//1,创建接收端和发送端。
public static void main(String[] args) throws SocketException {
DatagramSocket send = new DatagramSocket(1919);
DatagramSocket rece = new DatagramSocket(10001);
这里接收端端口号必须和发送数据包时指定的端口号一致。
new Thread(new Send(send)).start();
new Thread(new Rece(rece)).start();
}
网络段,网络位,广播位
比如192.168.1.x x可以从0取到255.但是分配给主机时0和255是不可以的。192.168.是网络段。192.168.1.0 0是网络位。表示的是192.168.1这个网络段。而255是广播位,192.168.1.255是向该网络段的所有主机广播。
TCP Socket服务。
客户端 Socket 服务端ServerSocket
对应udp的发送端和接收端。
可通过Socket类中的getInputStream()和getOutputStream()来获取网络流(即用于网络通信的io流)
而服务端没有获取流的方法,而是通过获取客户端对象,然后再通过客户端获取流。
服务端获取客户端的对象用accept()方法
Socket s=ss.accept();
TCP的练习 客户端和服务端的互访
客户端需要给服务端发送一个信息,并接收服务端返回的信息。
说明客户端这边既有读,又有写。
public class ClientDemo2 {
public static void main(String[] args) throws UnknownHostException, IOException {
//1,创建客户端socket对象。明确具体的主机和端口。
Socket s = new Socket("192.168.1.100",10003);
//2,获取输出流对象。
OutputStream out = s.getOutputStream();
out.write("服务端,你好啊!".getBytes());
//3,获取输入流对象。
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
String text = new String(buf,0,len);
System.out.println(text);
//3,关闭资源。
s.close();
服务端;
public class ServerDemo {
public static void main(String[] args) throws IOException {
读取客户端的数据,显示在显示器上,并给客户端一个回馈信息。
//1,创建tcp服务端对象。
ServerSocket ss = new ServerSocket(10003);
//2,获取客户端对象。
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
获取客户端对象中的客户端ip地址,这步实际中很重要
System.out.println(ip+".......connected");
//3,通过客户端的读取流对象取客户端发来的信息。
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
String text = new String(buf,0,len);
System.out.println(text);
//4,调用socket的输出流,给客户端一个回馈。
OutputStream out = s.getOutputStream();
out.write("我很好,收到!".getBytes());
//5,关闭资源。
s.close();先关闭客户端
ss.close();
}
上传文本文件UploadTextClient 、UploadTextServer
readLine()方法的底层是read()方法。是阻塞式
发送文件完成后 需给服务端发送一个传送结束标记。可自定义结束标记一般为事件的时间毫秒值。一般使用Socket对象提供的
shutdownOutput()方法。
上传多次 如何处理重名 如何使得服务端一直处于接受状态
File dir = new File("c:\\mypic");
if(!dir.exists())
dir.mkdir();//如果没有该目录则创建该目录用于存储。
int count = 1;
File file = new File(dir,ip+".jpg");
while(file.exists()){
file = new File(dir,ip+"("+(count++)+").jpg");//区别重名问题
}
//目的:文件
FileOutputStream fos = new FileOutputStream(file);
使得服务端处于接受状态
ServerSocket ss=new ServerSocket(端口号);
while(true){
服务端代码
}
常见的客户端和服务端。
客户端:浏览器。
服务端:Tomcat。
开发结构有两种:
1,C/S结构。
client / server 客户端和服务端。
特点:
1,客户端和服务端的软件都需要程序员进行编写。
2,客户端维护起来较为麻烦。
3,客户端的存在可以将一部分运算分离到客户端来运行,减轻了服务器端的压力。
2,B/S结构。
browser / server 浏览器和服务端。
特点:
1,客户端不用程序员编写,直接使用系统中具备的浏览器软件作为客户端即可。
程序员只需要编写服务器端就哦了。
2,维护起来也很容易,因为只要维护服务器即可。
3,所有的运算都在服务器端,相对压力较大。
----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------