OSI参考模型,注意看一下 TCP,UDP的协议名字,英文 网络传输的三要素: IP地址,端口,协议。 网络中计算机的唯一标识
IP地址表示形式是“点分十进制” IP组成:网络好短+主机号段。 IP地址的分类:
A类:1.0.0.1----127.255.255.254 10.x.x.x是私有地址 第一号段是网络断,后三段是主机号,即主机的个数 B类:128.0.0.1---191.255255.254 172.16.0.0---172.31.255.255是私有地址,前二段为网络号段 C类:192.0.0.1--223.255.255.254 192.168.x.x是私有地址。 前三段是网络段。 D类:224.0.0.1--239.255.255.254 240.0.0.1---247.255.255.254
特殊的IP地址:127.0.0.1回环地址
x.x.x.255广播地址
x.x.x.0网络地址。 InetAddress 是IP地址类 如果一个类没有构造方法
InetAddress address=InetAddress.getByName("主机名或者IP地址"); 根据主机名或者IP地址的字符串表示得到IP地址对象, 这样可以拿别人的IP地址或者主机名。
获得主机名: address.getHostName();
获得IP地址 address.getHostAddress(); 端口号:正在运行的程序的标识
范围:0-65535其中0-1024系统使用或者保留端口。 协议:
常用:
Socket:网络套接字:需啊哟IP地址和端口 UDP协议:DatagramSocket 数据包Socket
创建发送端Socket对象 DatagramSocket ds=new DatagramSocket() 创建数据,并把数据打包 DatagramPacket dp=new DatagramPacket(byte[] buf,int length,InetAddress address,int port) 调用Socket对象的发送数据包 ds.send(dp); ds.receive(dp)阻塞的接收、 释放资源 ds.close();
简答的发送代码:
- DatagramSocket ds=new DatagramSocket();
- byte[] buf="hello,UDP发送数据!".getBytes();
- int length=buf.length;
- InetAddress address=InetAddress.getByName("192.168.31.157");
- int port=12345;
- DatagramPacket dp=new DatagramPacket(buf, length, address, port);
- ds.send(dp);
- ds.close();
复制代码
接收代码: - DatagramSocket ds=new DatagramSocket(12345);
- byte[] buf=new byte[1024];
- int length =buf.length;
- DatagramPacket dp=new DatagramPacket(buf, length);
-
- ds.receive(dp);
- InetAddress address=dp.getAddress();
- String hostAddress=address.getHostAddress();
- String computerName=address.getHostName();
- byte[] buf2=dp.getData();
- int dataLength=dp.getLength();
- String dataString=new String(buf2, 0, dataLength);
- System.out.println(computerName+":"+hostAddress+" "+dataString);
- ds.close();
复制代码
UDP图解
多线程UDP,注意SendThread和ReceiveThread实现Runable接口 - DatagramSocket dsSend=new DatagramSocket();
- DatagramSocket dsReceive=new DatagramSocket(12345);
- SendThread st=new SendThread(dsSend);
- ReceiveThread rt=new ReceiveThread(dsReceive);
-
- Thread t1=new Thread(st);
- Thread t2=new Thread(rt);
- t1.start();
- t2.start();
复制代码
TCP协议:客户端类是Socket类服务器端是ServerSocket 服务器端的socket的 accept()和read()是阻塞式 - Socket s=new Socket("192.168.31.157", 12345);
- OutputStream os=s.getOutputStream();
- os.write("hello 你好".getBytes());
- s.close();
复制代码
服务器端: - Socket s=new Socket("192.168.31.157", 12345);
- OutputStream os=s.getOutputStream();
- os.write("hello 你好".getBytes());
- s.close();
复制代码
优化:client -
- Socket s=new Socket("192.168.31.157",12345);
-
- BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
- BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
-
- String line=null;
- while((line=br.readLine())!=null){
- if ("886".equals(line)) {
- break;
- }
- bw.write(line);
- bw.newLine();
- bw.flush();
- }
- s.close();
- }
复制代码
Server
- ServerSocket ss=new ServerSocket(12345);
- Socket s=ss.accept();
- BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream()));
- String line=null;
- while((line=br.readLine())!=null){
- System.out.println(s.getInetAddress().getHostAddress()+":"+line);
- }
- s.close();
复制代码
读取文件时可以做为null作为结束信息的,但是在通道内不能以null为技术信息。如果这样判断,服务器会一直等待客户端传送数据,
解决办法:需要自定义一个结束标记。但是如果文本里有就会出错,所以需要另一种解决方案。
s.shutdownOutput()作为socket流的结束。通知对方发送完成。 注意必须用flush() 否则出现字节丢失 现象 服务器端如果用while(true)接收客户端容易有问题,一个需要等待另一个完成才行。
解决办法是多线程。
|
|