不同的操作系统,不同的硬件设备上都能够联网,是因为互联网设计规定了一套标准,这套标准就被称为网络协议,网络协议规定了网络传输的格式,速率和方式;
是一组协议:HTTP ,FTP,SMTP,DNS
TCP: 传输控制协议
IP: 互联网协议
TCP/IP 协议的分层:
应用层:上位机应用程序,比如说 qq,用来产生数据和显示数据
传输层:端口号 加入一些标志位,保证数据传输的准确性
网络层:ip 地址 用来寻找对方电脑在哪里
链路层:网卡驱动 用来发送或接收数据
在一个网络中 ip 地址可以唯一标识一台电脑。
ipv4:xxx.xxx.xxx.xxx 点分十进制 32 个二进制位来描述 ip:21 个亿
ipv6:128 个二进制位来描述 ip:无数个
就是联网的每一个应用程序制定一个编号,编号可以唯一标识一个应用程序
1-65535
1-1024: 系统使用
1024-6000: 系统保留
>6000 自己使用
一台电脑的应用程序想和另一台电脑的一个程序通信 必须知道 ip 地址和端口号
面向无连接的协议,两台电脑在通信之前不需要建立连接,发送端只管发送,不会关心接收端是否已经收到,或者接收端是否存在
优点:数据传输速度快,效率高
缺点:数据安全性不高,数据容易丢失;
应用场景:电话会议,视频直播,网络会议----> 实时性
两台电脑在通信之前必须建立连接(三次握手),每次发送完数据,都会有一个反馈信息。
优点:数据安全性高,可靠性强
缺点:传输数度慢,效率低
应用场景:密码管理,金融支付,理财系统
- /*
- * InetAddress类用来描述一台电脑的信息:ip地址,计算机名和其他信息
- * public static InetAddress getLocalHost();可以获取本地电脑主机的信息
- * public static InetAddress getByName(String host);可以获取任意电脑主机的信息
- */
- public static void main(String[] args) throws Exception {
- //获取本地电脑主机的信息
- InetAddress address = InetAddress.getLocalHost();
- //使用getHostAddress()方法获取本地的ip地址
- String ip = address.getHostAddress();
- //使用getHostName()方法获取本地主机名
- String hostName = address.getHostName();
- //-------------------------getByName()方法的使用---------------------------------
- //获取指定指定主机的电脑信息
- InetAddress bdAddress = InetAddress.getByName("www.baidu.com"); //这里参数可以是网址,ip地址,和主机名
- //获取百度的ip地址
- String baiDuIp = bdAddress.getHostAddress();
- System.out.println("百度的IP地址是:" + baiDuIp);
- //获取百度的主机名
- String baiDuHostName = bdAddress.getHostName();
- System.out.println("百度的主机名是:" + baiDuHostName);
- }
1. 使用 udp 实现发送端的编写:
- public class SendDemo {
- public static void main(String[] args) throws IOException {
- //1:建立一个码头,该程序有一个对外连接的窗口
- /*
- * 套接字
- */
- DatagramSocket ds = new DatagramSocket();
- //2:准备要发送的货物:数据
- byte[] bytes = "hello udp!!!!".getBytes();
- //3:准备一个集装箱,将货物取装入集装箱
- /*
- * 参1:你要发送的数据
- * 参2:你要发送的字节长度
- * 参3: 表示接收端的ip地址
- * 参4: 表示接收端的端口号
- */
- //"192.168.65.103" --->InetAddress
- InetAddress address = InetAddress.getByName("192.168.65.255");
- DatagramPacket dp = new DatagramPacket(bytes, bytes.length, address, 8888);
- //4: 发送集装箱
- ds.send(dp);
- //5:关流
- ds.close();
- }
- }
- public class ReceiveDemo {
- public static void main(String[] args) throws IOException {
- //1:建立一个码头,并绑定端口
- DatagramSocket ds = new DatagramSocket(8888);
- //2:准备一个空的集装箱,用来接收数据
- /*
- * 参1:表示要接收的数据存放在哪个字节数组
- * 参2:表示要接收的数据长度
- */
- byte[] bytes = new byte[1024]; //"hello" ip 和端口
- DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
- //3:接收数据
- ds.receive(dp); //如果没有接收到数据,则该方法阻塞
- //4:从集装箱中获取数据
- byte[] data = dp.getData(); //"hello"
- int length = dp.getLength();
- //获取发送端的ip
- InetAddress address = dp.getAddress();
- String ip = address.getHostAddress();
- //5:打印接收到的数据
- System.out.println(ip + ":" + new String(data, 0, length));
- }
- }
图片上传案例:
- public class ClientDemo {
- public static void main(String[] args) throws IOException {
- //1:获取文件的输入流(读)
- FileInputStream fis = new FileInputStream("a.jpg");
- // BufferedInputStream bufis = new BufferedInputStream(fis);
- //2:获取套接字的输出流
- InetAddress address = InetAddress.getLocalHost();
- Socket socket = new Socket(address, 9999);
- OutputStream os = socket.getOutputStream();
- // BufferedOutputStream bufos = new BufferedOutputStream(os);
- //3:将从文件输入流读取的数据写到套接字的输出流
- byte[] bytes = new byte[1024];
- int len = 0;
- while ((len = fis.read(bytes)) != -1) {
- os.write(bytes, 0, len);
- }
- //关闭输出流
- // socket.close(); //输入流和输出流都关闭
- socket.shutdownOutput(); //值关闭输出流
- //--接收反馈信息
- //3.1获取套接字的输入流
- InputStream is = socket.getInputStream();
- //3.2 读取数据
- len = is.read(bytes);
- System.out.println(new String(bytes, 0, len));
- //4:关流
- socket.close();
- fis.close();
- }
- }
- public class ServerDemo {
- public static void main(String[] args) throws IOException {
- //1:获取套接字的输入流
- ServerSocket sSocket = new ServerSocket(9999);
- Socket cSocket = sSocket.accept();
- InputStream is = cSocket.getInputStream();
- //2:获取文件的输出流
- FileOutputStream fos = new FileOutputStream("D:\\Server\\a.jpg");
- /*
- * while循环要想结束必须read方法读取-1,在普通文件的读取中,读取到文件末尾就能-1
- * 但是套接字没有文件末尾,所以不能返回-1
- *
- * 如何让服务器读取到-1?
- * 只要让客户端把输出流进行关闭
- */
- //3:将从套接字输入流读取的数据写入文件的输出流
- byte[] bytes = new byte[1024];
- int len = 0;
- while ((len = is.read(bytes)) != -1) {
- fos.write(bytes, 0, len);
- }
- //--在这里给客户端反馈
- //3.1 获取套接字的输出流
- OutputStream os = cSocket.getOutputStream();
- //3.2 发送反馈信息
- os.write("上传成功啦!".getBytes());
- //4:关流
- fos.close();
- cSocket.close();
- sSocket.close();
- }
- }
客户端:
- public class ClientDemo {
- public static void main(String[] args) throws IOException {
- //1:获取文件的输入流(读)
- FileInputStream fis = new FileInputStream("a.jpg");
- // BufferedInputStream bufis = new BufferedInputStream(fis);
- //2:获取套接字的输出流
- InetAddress address = InetAddress.getLocalHost();
- Socket socket = new Socket(address, 10086);
- OutputStream os = socket.getOutputStream();
- // BufferedOutputStream bufos = new BufferedOutputStream(os);
- //3:将从文件输入流读取的数据写到套接字的输出流
- byte[] bytes = new byte[1024];
- int len = 0;
- while ((len = fis.read(bytes)) != -1) {
- os.write(bytes, 0, len);
- }
- //关闭输出流
- // socket.close(); //输入流和输出流都关闭
- socket.shutdownOutput(); //值关闭输出流
- //--接收反馈信息
- //3.1获取套接字的输入流
- InputStream is = socket.getInputStream();
- //3.2 读取数据
- len = is.read(bytes);
- System.out.println(new String(bytes, 0, len));
- //4:关流
- socket.close();
- fis.close();
- }
- }
服务器端:
多线程:
- public class ServerDemo {
- public static void main(String[] args) throws IOException {
- ServerSocket sSocket = new ServerSocket(10086);
- //有多少个请求,accept就执行多少次
- while (true) {
- Socket cSocket = sSocket.accept();
- //每来一个请求,就创建一个线程,去处理请求
- Thread t = new Thread(new MyRunnable(cSocket));
- t.start();
- }
- }
- }
- public class MyRunnable implements Runnable {
- private Socket cSocket;
- public MyRunnable(Socket cSocket) {
- this.cSocket = cSocket;
- }
- public MyRunnable() {}
- //a.txt --->a(2).txt
- @Override public void run() {
- try {
- //1: 获取套接字的输入流
- InputStream is = cSocket.getInputStream();
- long time = System.currentTimeMillis();
- //2:获取文件的输出流
- FileOutputStream fos = new FileOutputStream("D:\\Server\\" + time + ".jpg");
- //3:将从套接字输入流读取的数据写入文件的输出流
- byte[] bytes = new byte[1024];
- int len = 0;
- while ((len = is.read(bytes)) != -1) {
- fos.write(bytes, 0, len);
- }
- System.out.println("while之后");
- //--在这里给客户端反馈
- //3.1 获取套接字的输出流
- OutputStream os = cSocket.getOutputStream();
- //3.2 发送反馈信息
- os.write("上传成功啦!".getBytes());
- //4:关流
- fos.close();
- cSocket.close();
- } catch(Exception e) {}
- }
- }
来源: http://www.bubuko.com/infodetail-2438763.html