网络编程:
TCP/IP模型 OSI模型.
TCP/IP模型
分为7层:
应用层 表示层 会话层 传输层(UDP或TCP协议) 网络层 数据链路层
对应的IOS模型为:
应用层 传输层 网际层 主机至网络层
数据的发送,通过一层一层向下一层层封装.到底层使用(比特流)的方式进行传递
到另一个电脑的物理层,再一层层解封装.到最后显示出结果.
网络编程的三要素:
1. 需要有IP地址
2. 必须有端口
3. 必须有协议(TCP协议,UDP协议)
IP:为每个地址的唯一标示
Ip地址:192.168.1.100
实质:每一个段落转换为2进制数.
这里是点分十进制法输出:
IP地址分为3类:
A类:第一个号段为网络号段,可以连接256^3台计算机(国家部门使用)
B类:前两个号段网络编号:可以连接256^2台计算机(大学里使用或者地方政府)
C类:前三个号段为网络编号,后一个号段为主机号段.(192.168.1.100)私人地址
回环地址:本地地址(127.0.0.1)
xxx.xxx.xxx.255
常用命令:ipconfig:查看ip
Ping ip地址:查看当前本机与这台pc机器的网络通信
每个计算机都有属于自己的端口号:
有效端口号:0-65535
保留端口号:0-1024
传输层中的TCP协议和UDP协议
TCP(服务器端与客户端)
1. 需要建立连接通道(使用的为基本的字节流)
2. 具有可靠性
3. 建立连接通道,因此传输效率低,
4. 传输文件无大小限制.
UDP协议(发送端与接收端)
1. 不需要建立连接
2. 不可靠性
3. 传输的效率高
4. 传输的文件有限制,不能超过64KB
InetAddress类表示 互联网协议(IP)地址
需要抛出一个异常:有可能找不到.
publicclass InetAdderssDemo {
publicstaticvoid main(String[] args) throws IOException {
InetAddress address = InetAddress.getByName("");
System.out.println(address);//打印的为本机地址:回环地址
String name = address.getHostName();
System.out.println(name);//localhost
String ip = address.getHostAddress() ;
System.out.println("ip:"+ip);
}
}
输出结果为:
localhost/127.0.0.1
localhost
ip:127.0.0.1
UDP协议(发送端-接收端):
接收端:
1. 创建接收端的Socket对象
2. 创建一个数据报包接受发送端送来的数据报包(接收容器)
3. 接收数据,调用DataSocket类中的接收的方法来接收数据包
ds.receive(dp)//阻塞式方法,有数据才发送
4. 解析数据报宝里的实际数据,显示在控制台上
注意:接收端只运行一次,当多次运行,会产生BingEceo0Exception:绑定异常
1. 创建UDP协议接收端中的④Scoket对象
2. 创建数据抱包
Eg(byte[]buf),字节的长度);
定义字节数组为缓存区.
3. 调用DataSocket里面接收的方法.
Socket对象的方法:receive
4. 解析数据报包里的实际数据,显示在控制台上.
首先通过数据报包得到一个Ip地址对象
解析发送端发送来的实际数据
//一次输出一行.
DDP:发送端:不需要建立连接通道:
1. 创建协议发送端Socket对象
2. 创建数据报包:通过数据包将数据发送到接收端
public DatagramPacket(byte[] buf, intlength ,InetAddress address,int port)
数组名,长度,IP地址,端口号
3. 调用UDO协议发送端的方法 send();
4. 关闭资源
两者都需要抛出异常或捕获异常
//发送端
publicclass SendDemo {
publicstaticvoid main(String[] args) throws IOException {
DatagramSocket ds = new DatagramSocket(); //UDP里面的Sock对象
//DatagramSocket:用来发送和接收数据报包的套接字。
String s="好多事情需要做,好忙";
byte[]bys=s.getBytes();//数组
int len=bys.length;//长度
InetAddress IA =InetAddress.getByName("192.168.10.101");//创建InetAddress对象,Ip地址对象
int port=10035;//端口号
DatagramPacket packet = new DatagramPacket(bys,len,IA,port);
//使用套接字流发送
ds.send(packet);
ds.close();
}
}
//接收端
publicclass ReseverDemo {
publicstaticvoid main(String[] args) throws IOException {
DatagramSocketds = new DatagramSocket(10035);//创建Socket对象,绑定端口号
//创建数据报包
//定义缓冲区,缓冲区遍历
byte[]bys=newbyte[1024];
DatagramPacket dp=new DatagramPacket(bys,bys.length);
//接收方法
ds.receive(dp);
//遍历到控制台上
InetAddress address = dp.getAddress();
String ip = address.getHostAddress(); //返回String IP地址
byte[] by = dp.getData();
int len=dp.getLength();
//将数组转化为字符串
String s=new String(by,0,len);
System.out.println(ip+"给您发送了"+s);
}
}
进一步优化:
将创建套接字流里链式链接输出
两者首先需要创建套接字流对象
不断的接收键盘录入的数据显示在控制台上
发送端:使用BufferReader
在while循环里面一次读取一行.
数据报包发送.最后关闭流资源
接收端:在while循环里面:数组遍历,
解析数据接收容器,获取里面的内容.然后打印
TCP
客户端和服务器端的交互
客户端步骤:
创建客户端的socket对象 获取通道的内流(输出流) 使用输出流对象写数据
关闭客户端的Socket对象
Socket s = newSocket("192.168.10.101", 10010) ;
OutputStream out= s.getOutputStream() ;
out.write("hello,TCP,我来了...".getBytes());
s.close() ;
服务器端
创建服务器端的socket对象,指定端口 服务器端需要监听客户端的连接
获取通道内的输入流 将数据获取到并显示到控制台
关闭服务器端的socket资源
ServerSocket ss= new ServerSocket(10010) ;
System.out.println("等待客户端连接...");
Socket s =ss.accept() ;
System.out.println("客户端已经连接...");
byte[] bys = newbyte[1024] ;
int len =in.read(bys) ;//获取到实际的字节数 (阻塞式)
String str = newString(bys, 0, len) ;
InetAddressaddress = s.getInetAddress() ;
String ip =address.getHostAddress() ;
System.out.println(ip+"传递的数据是:"+str);
s.close() ;
要求:客户端键盘录入,服务器将录入的内容输出到文本文件
客户端:
Socket s=new Socket(“192.168.10.101”,8888);
//键盘录入:IO流的形式
BufferedReader br=new BufferedReader(newInputStreamReader(System.in));
//封装通道内的流
BufferedWriter bw=new BufferedWriter(newOutputStreamWriter(s.getOutputStream()));
String line=null;
While((line=br.readline())!=null){
If(“over”.equals(line)){
break;
}
bw.write(line);
bw.newLine();
bw.flush();
}
s.close();
}
服务器端:
SeverSockert ss=new SeverSocket(8888);
Socket s=ss.accept();
//封装通道内的流
BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream()));
//服务器端输出一个文本文件
BufferedWriter bw=new BufferedWriter(new FileWriter(“a.txt”));
//服务器端通道内的流读取客户端发送的数据,将数据一次写入到a.txt文件
String line=null;
While((line=br.readLine())!=null){
Bw.write(line);
Bw.newLine();
Bw.flush();
}
s.close();
bw.close();
}
}