------- android培训、java培训、期待与您交流! ----------
1)网络模型
①OSI(Open System InterConnection开放系统互连)参考模型
②TCP/IP参考模型
2)网络通讯要素
①IP地址:InetAddress
网络中标识的设备
不易记忆,可以用主机名
本地回环地址:127.0.0.1 主机名:localhost
②端口号
用于标识进程的逻辑地址,不同进程的标识
有效端口:0~65535,其中0~1024是系统使用的端口或者保留端口
③传输协议
通讯的规则
常见协议:TCP(传输控制协议)和UDP(数据报文协议)
④TCP和UDP
UDP:生活中像“对讲机”,就拥有UDP的特点,“QQ”,“飞秋”等都是UDP的典型例子
1.将数据以及源和目的封装成数据包,不需要建立连接
2.每个数据报的大小限制在64k内
3.因无连接,是不可靠协议
4.因无连接,速度快
TCP:生活中像“电话”,就拥有TCP的特点,“金山毒霸”等都是TCP的例子
1.建立连接,形成传输数据的通道
2.在数据通道中传输数据,数据量比较大
3.通过三次握手建立连接,是可靠协议
①A方发送:“你在不在”
②B方回复:“我在”
③A方确认:“我知道了”
4.因建立连接,效率相对比较低
3)Socket:就是网路服务的一种机制,通信的两端都有Socket,网络通信其实就是Socket的通信,数据是在Socket间通过IO传输
4)java中网络编程的类以及接口都在java.net包中。其中有很多重要的类,包括如下几种:
①InetAddress类,InetAddress4类以及InetAddress6类等
②遵循UDP传输协议的类:
DatagramSocket类:此类既可以发送,又可以接收数据
DatagramPacket类:此类表示数据报包,数据报包用来实现无连接投递服务
案例:结合多线程的知识,开发个聊天小程序
①发送端类:SendInfor.java
//聊天小程序的发送端
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class SendInfor implements Runnable {
DatagramSocket ds;
public SendInfor(DatagramSocket ds)
{
this.ds=ds;
}
public void run() {
//
try {
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String line=null;
while((line=br.readLine())!=null)
{
byte[] buf=line.getBytes();
DatagramPacket dp=new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.123"),10002);
ds.send(dp);
if(line.equals("over"))
break;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
ds.close();
}
}
}
②接收端类:Receive.java
//聊天小程序的接收端
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class Receive implements Runnable {
DatagramSocket ds;
public Receive(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();
int port=dp.getPort();
String text=new String(dp.getData(),0,dp.getLength());
System.out.println(ip+":"+port+text);
if(text.equals("over"))
break;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
ds.close();
}
}
}
③主线程:ChatDemo.java
import java.net.DatagramSocket;
import java.net.SocketException;
public class ChatDemo
{
public static void main(String[] args)
{
try {
DatagramSocket rece=new DatagramSocket(10002);
DatagramSocket send=new DatagramSocket();
new Thread(new SendInfor(send)).start();
new Thread(new Receive(rece)).start();
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
③遵循TCP协议的类:Socket类和ServerSocket类
案例:1.客户端与服务器端演示三次握手,传度数据
①Client.java
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
//客户端向服务器端发送数据,同时接收服务器端的响应
public class Client {
public static void main(String[] args) throws IOException, IOException {
//客户端发送数据到服务器端
//1.创建客户端socket服务
Socket socket=new Socket("192.168.1.104",10002);
//2.接收socket中的输出流
OutputStream out=socket.getOutputStream();
//3.使用输出流将指定的数据写出去
out.write("客户端向服务器端发送请求".getBytes());
//客户端读取服务器端返回的数据
InputStream in=socket.getInputStream();
byte[] buf=new byte[1024];
int len=in.read(buf);
String text=new String(buf,0,len);
System.out.println(text);
//关闭资源
socket.close();
}
}
②Server.java
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
//服务器向客户端发送数据,同时接收客户端的响应
public class Server
{
public static void main(String[] args) throws IOException {
//服务器端接收客户端的响应
//1.创建服务器server对象
ServerSocket ss=new ServerSocket(10002);
//2.获取连接过来的socket对象
Socket socket=ss.accept();//阻塞式
//3.通过socket获取输入流,读取客户端发送来的数据
InputStream in=socket.getInputStream();
byte[] buf=new byte[1024];
int len=in.read(buf);
String text=new String(buf,0,len);
System.out.println(text);
//服务器端返回数据给客户端
OutputStream out=socket.getOutputStream();
out.write("收到".getBytes());
//关闭资源
ss.close();
socket.close();
}
}
案例2:从客户端上传一个文本文件到服务器端
①Client_uploadText.java
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
//客户端上传文本文件到服务器
public class Client_uploadText
{
public static void main(String[] args) throws IOException {
//1.创建客户端Socket对象,要指定ip地址号,以及端口号
Socket socket=new Socket("192.168.1.104",10006);
//2.从客户端读取指定的要上传的文件
BufferedReader bufr=new BufferedReader(new FileReader("d:\\file.txt"));
//3.获取客户端的输出流,即socket流
//BufferedWriter bufIn=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));这种方式跟下面这种方式都可以
PrintWriter bufIn=new PrintWriter(socket.getOutputStream(),true);
String line=null;
while((line=bufr.readLine())!=null)
{
//bufIn.write(line+"\r\n");
bufIn.println(line);
bufIn.flush();
}
//4.向服务器段发送流结束标记
socket.shutdownOutput();
//5.读取服务器端的响应
BufferedReader server=new BufferedReader(new InputStreamReader(socket.getInputStream()));
String str=server.readLine();
System.out.println(str);
bufr.close();
socket.close();
}
}
②Server_ReceiveText.java
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
//服务器接收客户端上传的文本文件,接收成功后,并且通知客户端"上传成功"
public class Server_ReceiveText
{
public static void main(String[] args) throws IOException {
//1.获取服务器端的Serversocket对象,并指定端口号
ServerSocket ss=new ServerSocket(10006);
//2.获取socket流
Socket socket=ss.accept();
System.out.println(socket.getInetAddress().getHostAddress()+"........connected");
//3.获取客户端发送来的数据,即读取该文件
BufferedReader bufr=new BufferedReader(new InputStreamReader(socket.getInputStream()));
//4.准备好准备写入的文件,将读取的数据写入到指定文件中
BufferedWriter bufw=new BufferedWriter(new FileWriter("d:\\server.txt"));
String line=null;
while((line=bufr.readLine())!=null)
{
bufw.write(line);
bufw.flush();
bufw.newLine();
}
//5.向客户端返回响应,发送“上传成功过去”
PrintWriter out=new PrintWriter(socket.getOutputStream(),true);
out.println("上传成功");
ss.close();
bufw.close();
}
}
此外在net包中还有Url(资源定位)类,Uri(资源标识)类,UrlConnection类等各有自己的职责,在此不再赘述。