java实现网络编程

网络通讯的三要素:
ip地址
端口号 端口号范围 0到65535 其中0到1023系统已经绑定使用不可以使用,从1024到65535可以使用!
协议

为什么需要加上一个协议呢?
举个例子因为不同的pc机器之间进行一个通信的时候,都会把数据发送出去,加入是A机器发送数据
到B机器,那么A机器首先会通过一个路由器a 然后把数据发送给B机器的时候首先会经过一个路由器b
那么这个路由器b需要解密这个路由器a发送的贞数据,所以所有的路由器厂商都是需要遵守一个协议,
有了这个协议,再加上ip和端口号就可以通信了!

ip地址:ip地址本质上就是一个32位的2进制数组成的!

    00000000-00000000-00000000-00000000

后来由于这个不好记忆,所以,就把这个ip地址切分成4分 每一份8bit(位) 所以每一份最大的数为2的8次幂
也即是0到255!

ip地址=网络号+主机号 网络号就是前面的部分前三部分 为什么是前面三位是由于子网掩码决定的!
ip地址的分类:
A类地址=一个网络号+三个主机号 2的24次幂 政府单位使用
B类地址=两个网络号+两个主机号 2的16次幂 事业单位使用
C类地址=三个网络号+一个主机号 2的8次幂 个人使用,注意我们一般使用的都是从这个一个ip中分发出来的!

操作ip地址的类InetAddress(ip类)
常用的方法:

 getLocalHost()
 getHostAddress()
 getHostName()
 getByName(ip或者主机名) 根据ip地址的字符串形式或者主机名来获取别人的ip地址对象

网络协议:

udp通信协议的特点:
1.将数据封装成一个数据包,面向无连接
2.每一个数据包的大小是64k
3.因为无连接,所以不可靠
4.因为不需要简历链接,所以速度快
5.udp通信是不分客户端和服务端的,只分接收端和发送端
例如:物管的对讲机,游戏。。

tcp通信协议的特点:
1.面向链接,有特有的通道
2.在链接中传输大量的数据
3.通过三次握手的机制建立链接,可靠协议
4.通信之前必须建立链接,效率低下
例如:打电话,文件的传送!

在java中网络通讯也可以叫做socket(插座)通讯 ,要求通讯的两台机器必须要安装socket
不同的协议就有不同的socket

1.Udp协议下的Socket:

DatagramSocket(udp插座服务)
DatagramPacket(数据包类)

udp通信实战:这个upd通信就像是码头一样的,货物都是放在集装箱中,发送到哪里去都

          是写在集装箱中的!

发送端步骤:
1.建立udp的服务
DatagramSocket datagramSocket =new DatagramSocket();
2.准备数据,把数据打包到数据包中
String data="这个是我的第一个udp例子";
3.创建了一个数据包
DatagramPacket packet=new DategramPacket(data.getBytes,data.getBytes.lenght,InetAddress.getLocalHost(),9000);
说明:这个数据包类Datagrampacket就是相当于码头的集装箱,送货到哪里的信息都是写在集装箱上的,所以这个构造方法

  带有参数 参数依次为:数据的byte数组 数据的大小 address地址  端口号

4.调用udp服务发送数据包
datagramSocket.sent(packet);
5.关闭资源 就是释放端口号
datagramSocket.close();

接受端步骤:
1.建立udp服务,并且需要监听一个端口
DatagramSocket socket=new DatagramSocket(9000); 这个是发送端定义的端口
2.准备一个空的数据包来接受数据
byte[] byf=new byte[1024];
DategramPacket packet=new DatagramPacket(buf,buf.length);
注意:由于是接受数据,所以不需要在创建数据包的时候,定义ip等数据了,只要一个缓冲数组即可!
3.调用udp服务接受数据
socket.receive(packet);
注意:这个reveive这个方法是一个阻塞性方法,没有接收到数据包之前都是一直处于等待状态!!!
4.打印接受到的数据
System.out.println("接受端接收到的数据为"+new String(buf,0,packet.getLenght()));
5.关闭资源
socket.close();

使用udp协议模拟feiq发送消息

准备知识:
feiq接受数据的格式:
version:time:sender:ip:flag:content
版本号 时间 发送人 ip 发送的标识(32) 32表示发送消息 内容

广播地址:
在udp协议中,有一个ip地址称作为广播地址,广播地址就是主机号为255的的地址
ip地址=网络号+主机号 如果网络号为192.168.15 那么这个广播地址为192.168.15.255

//使用udp协议给feiq发送消息的实现
public class FeiQDemo{

public static void main(String[] args){

   //建立udp服务,就是建立socket链接,也就是建立码头,是发送,所以不需要ip地址的
   DatagramSocket socket=new DatagramSocket();
   //准备数据,把数据封装到数据包中
   String data=getData("你好!");
   //准备数据包,这个数据包带有一定的信息,就像是集装箱一样
   DatagramPacket packet=new DatagramPacket(data.getBytes(),data.getBytes().length,InetAddress.getByName("192.168.21.14"),2425);
   //发送数据
   socket.send(packet);
   //关闭资源
   socket.close();

}

//创建一个方法封装feiq需要的发送数据格式
public static String getData(Stirng content){

StringBuilder sb=new StringBuilder();
sb.append("1.0:");
sb.append(System.currentTimeMillis()+":");
sb.append("习大大:");
sb.append("192.168.88.88");
sb.append(content);
return sb.toString();

}

}

Tcp通信的特点:
1.tcp是基于io流进行数据的传输的,面向链接
2.tcp进行数据传输的时候,是没有大小来限制的
3.tcp是面向无链接的,通过三次握手机制来保证链路的畅通,可靠协议
4.速度慢
5.tcp是严格区分客户端和服务端的

tcp协议下的socket:(tcp协议下两个类)
socket 客户端
serverSocker 服务端

tcp客户端的步骤:
1.建立tcp的服务
Socket socket=new Socket(InetAddress.getLocalHost(),9090);
注意:由于tcp客户端一旦启动就马上需要和服务端进行连接,所有这个构造函数带有ip和端口
2.获取socket输出流对象
OutputStream outputstream=socket.getOutputStream();
//利用输出流对象把数据写出去
outputstream.write("服务端你好".getBytes());
//关闭资源
socket.close();

tcp服务端的步骤:
1.建立tcp的服务端,并且监听一个端口
ServerSocket serverSocket=new ServerSocker(9090);
2.接受客户端的链接
Socket socket=serverSocker.accept();
注意:接受客户端的链接这个方法是一个阻塞性的方法,如果没有客户端链接上去,就不会往下走!
3.获取输入流对象,读取客户端发送的内容
InputStream inputStream=socket.getInputStream();
byte[] buf=new byte[1024];
int length=0;
length=inputStream.read(buf);
System.out.println("服务端接受"+new String(buf,0,length));
//关闭资源
serverSocket.close();

疑问:为什么ServerSocket 不设计一个getInputStream和getOutputStream方法?
因为如果一个服务端有两个客户端与之连接,如果这个两个客户端都调用outputStream方法
向服务端发送信息的时候,那么当这个服务端也调用outputStream回信息的时候,不知道是
回给哪一个客户端,所以最好的方案就是当每一个客户端通过accept()方法,然后形成一个
单独的socket通道,那么这样以后,服务端给客户端回信息的时候,就会相当于是给单独的
客户端回信息,这样就不会错乱!