网络编程
1.概述
- 计算机网络:
- 计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线程连接起来,在网络操作系统。网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统
- 网络编程的目的:
- 无线电台…传播交流信息,数据交换,通信
- 想要达到这个效果需要什么?
- 如何准确的定位网络上的一台主机。192.168.16.124:端口,定位到这个计算机上的某个资源
- 找到了这个主机,如何传输数据呢?
- Javaweb:网页编程 B/S
- 网络编程: TCP/IP C/S
2.网络通信的要素
-
如何实现网络的通信?
-
通信双方地址:
- IP
- 端口号
- 192.168.16.124:5900
规则:网络通信的协议
-
TCP/IP参考模型
-
-
重点学习传输层:
- 传输层(Transport): 传输层 TCP/UDP
-
小结:
- 网络编程中有两个主要的问题
- 如何准确得到定位到网络上的一台或者多台主机
- 找到主机之后如何进行通信
- 网络编程中的要素
- IP和端口号
- 网络通信协议 TCP/UDP
- 万物皆对象
- 网络编程中有两个主要的问题
3.IP
- IP地址:InetAddress
- 唯一定位一台网络上计算机
- 127.0.0.1:本机 localhost
- ip地址的分类
- ipv4/ipv6
- Ipv4 :127.0.0.1,4个字节组成。0~255,42亿,30亿都在北美,亚洲4亿,2011年就用尽了
- Ipv6 :128位。8个无符号整数
- 公网(互联网)——私网(局域网)
- ABCD类地址
- 192.168.xx.xx,专门给组织内部使用的
- 域名:记忆IP问题
- IP:www.vip.com 好的域名值钱
- ipv4/ipv6
import java.net.InetAddress;
public class Address {
public static void main(String[] args) throws Exception{
//查询本机地址
System.out.println( InetAddress.getByName("127.0.0.1"));
System.out.println(InetAddress.getByName("localhost"));
System.out.println(InetAddress.getLocalHost());
//查询网站ip地址
System.out.println(InetAddress.getByName("www.baidu.com"));
}
}
-
常用方法:
inetAddress.getAddress(); inetAddress.getCanonicaHostName();//规范的名字 inetAddress.getHostAddress();//ip inetAddress.getHostName();//域名,或者自己电脑的名字
4.端口
-
端口表示计算机上的一个程序的进程:
- 不同的进程有不同的端口号!用来区分软件
- 被规定0~65535
- TCP/UDP:65535*2 tcp:80,dup:80.单个协议下,端口号不能冲突
- 端口分类
- 共有端口0~1023
- HTTP:80
- HTTPS:443
- FTP:21
- Telent:23
- 程序注册端口:1024~49151,分配用户或者程序
- Tomcat:8080
- MySQL:3306
- Oracle:1521
- 动态、私有49152~65535
-
cmd中输入
C:\Users\admin>netstat -ano//查看所有的端口 C:\Users\admin>netstat -ano|findstr "1068"//查看指定的端口 C:\Users\admin>tasklist|findstr "1068"//查看指定的端口的进程
-
ctrl+shift+Esc 打开任务管理器
InetSocketAddress socketAddress=new InetSocketAddress("localhost",8080); System.out.println(socketAddress.getAddress());//地址端口 System.out.println(socketAddress.getHostName());//地址 System.out.println(socketAddress.getPort());//端口
5.通信协议
-
协议:约定,就好比我们现在说的是普通话
-
网络通信协议:速度,传输码率,代码结构,传输控制…
-
问题:非常的复杂?
- 大事化小,分层。
-
TCP/IP协议簇:实际上是一组协议
-
重要:
- TCP:用户传输协议
- UDP:用户数据报协议
-
出名的协议:
- ICP
- IP:网络互联协议
-
TCP/UDP对比
-
TCP:打电话
-
连接,稳定
-
三次握手,四次挥手
-
最少需要三次,保证稳定连接
A:你瞅啥? A:我要走了 B:瞅你咋地? B:我真的要走了吗? A:干一场! B:你真的要走了吗? A:我真的要走了!
-
客户端、服务端
-
传输完成,释放连接,效率低
-
-
UDP: 发短信
- 不连接,不稳定
- 客户端、服务端:没有明确的界限
- 不管有没有准备好,都可以发给你
- 导弹
- DDOS:洪水攻击!(饱和攻击)
-
6.TCP
-
客户端
-
连接服务器 Socket
-
发送信息
public class TCPClient { public static void main(String[] args) { Socket socket=null; OutputStream os=null; try { //1.要知道服务器的地址,端口号 InetAddress serverIP=InetAddress.getByName("127.0.0.1"); int port=8000; //2.创建一个socket连接 socket=new Socket(serverIP,port); //3.发送信息IO流 os=socket.getOutputStream(); os.write("你好欢迎看到我的笔记".getBytes()); } catch (IOException e) { e.printStackTrace(); } if (os!=null){ try{ os.close(); }catch (Exception e){ e.printStackTrace(); } } if (socket!=null){ try{ socket.close(); }catch (Exception e){ e.printStackTrace(); } } } }
-
-
服务端
-
建立服务器的端口 ServerSocket
-
等待用户的链接 accept
-
接受用户的信息
public class TCPServer { public static void main(String[] args) { ServerSocket serverSocket=null; Socket socket=null; InputStream is=null; ByteArrayOutputStream bos=null; try { //1.我得有一个地址 serverSocket=new ServerSocket(9999); //2.等待客户端连接过来 socket=serverSocket.accept(); //3.读取客户端的数据 is=socket.getInputStream(); //管道流 bos=new ByteArrayOutputStream(); byte[] buffer=new byte[1024]; int len; while ((len=is.read(buffer))!=-1){ bos.write(buffer,0,len); } System.out.println(bos.toString()); bos.close(); is.close(); socket.close(); serverSocket.close(); } catch (IOException e) { e.printStackTrace(); } } }
-
注意:客户端和服务端两个是一个项目,运行时先启动服务端,在启动客户端。
7.TCP文件上传
-
I(InputStream)O(OutputStream)流 I读取 O写入 O写入内容 I读取O写入的内容
-
服务端
public class TCPServerFile { public static void main(String[] args) { try { //1.创建服务器 ServerSocket serverSocket=new ServerSocket(9000); //2.监听客户端的连接 Socket socket=serverSocket.accept();//阻塞式建通,会一直等待客户端连接 //3.获取输入流 InputStream is=socket.getInputStream(); //4.文件输出 FileOutputStream fos=new FileOutputStream(new File("renwu.jpg")); byte[] buffer=new byte[1024]; int len ; while ((len=is.read(buffer))!=-1){ fos.write(buffer,0,len); } //通知客户端我接受完毕了 OutputStream os=socket.getOutputStream(); os.write("我接受完毕了,你可以断开了".getBytes()); //关闭资源 fos.close(); is.close(); socket.close(); serverSocket.close(); } catch (IOException e) { e.printStackTrace(); } } }
-
客户端
public class TCPClientFile { public static void main(String[] args) { try { //1.创建一个Socket连接 Socket socket=new Socket(InetAddress.getByName("127.0.0.1"),9000); //2.创建一个输出流 OutputStream os=socket.getOutputStream(); //3.读取文件 FileInputStream fis= new FileInputStream(new File("C:\\Users\\admin\\IdeaProjects\\JavaEE\\src\\TCPFile\\aa.jpg")); //4.输出文件 byte[] buffer=new byte[1024]; int len ; while ((len=fis.read(buffer))!=-1){ os.write(buffer,0,len); } //通知服务器,我已经结束了 socket.shutdownOutput(); //我已经传输完了 //确定服务器接收完毕,才能够断开连接 InputStream inputStream = socket.getInputStream(); //string byte[] ByteArrayOutputStream bos = new ByteArrayOutputStream(); byte[] buffer2=new byte[2014]; int len2; while ((len2=inputStream.read(buffer2))!=-1){ bos.write(buffer2,0,len2); } System.out.println(bos.toString()); //5.关闭资源 bos.close(); inputStream.close(); fis.close(); os.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } }
-
Tomcat
- 服务端
- 自定义 S
- Tomcat服务器 S
- 客户端
- 自定义 C
- 浏览器 B
- 服务端
8.UDP
-
发短信:不用连接,需要知道对方的地址
-
客户端
-
发送信息,不需要连接服务器
public class UDPClient { public static void main(String[] args) { try { //1.建立一个Socket DatagramSocket socket=new DatagramSocket(); //2.建个包 String msg="你好啊,服务器"; InetAddress localhost=InetAddress.getByName("localhost"); int port=9090; //数据,数据的起始长度,需要发给谁 DatagramPacket packet=new DatagramPacket(msg.getBytes(),0,msg.getBytes().length,localhost,port); //3.发送包 socket.send(packet); //4.关闭流 socket.close(); } catch (IOException e) { e.printStackTrace(); } } }
-
-
服务端
-
接收信息,还是等待客户端的连接
public class UDPServer { public static void main(String[] args) { try { //开放端口 DatagramSocket socket=new DatagramSocket(9090); //接收数据包 byte[] buffer=new byte[1024]; DatagramPacket packet=new DatagramPacket(buffer,0,buffer.length); socket.receive(packet);//阻塞接收 System.out.println(packet.getAddress().getHostAddress()); System.out.println(new String(packet.getData(),0,packet.getLength())); //关闭连接 socket.close(); } catch (IOException e) { e.printStackTrace(); } } }
-
-
-
循环发送信息
-
发送端
public class UDPSend { public static void main(String[] args) { try { DatagramSocket socket=new DatagramSocket(8888); //准备数据:控制台读取system.in BufferedReader reader=new BufferedReader(new InputStreamReader(System.in)); while (true){ String data = reader.readLine(); byte[] datas=data.getBytes(); DatagramPacket packet=new DatagramPacket(datas,0,datas.length,new InetSocketAddress("localhost",6666)); socket.send(packet); if (data.equals("bye")){ break; } } socket.close(); } catch (IOException e) { e.printStackTrace(); } } }
-
接收端
public class UDPReceive { public static void main(String[] args) { try { //开放端口 DatagramSocket socket=new DatagramSocket(6666); while (true){ //准备接收包裹 byte[] buffer=new byte[1024]; DatagramPacket packet=new DatagramPacket(buffer,0,buffer.length); socket.receive(packet);//阻塞接收包裹 //断开连接 byte byte[] date=packet.getData(); String receiveDate = new String(date, 0, date.length); System.out.println(receiveDate); if (receiveDate.equals("bye")){ break; } } //关闭连接 socket.close(); } catch (IOException e) { e.printStackTrace(); } } }
-
-
在线咨询:两个人都可以是发送方,也可以是接收方
-
UPD多线程在线咨询
-
发送端
public class TalkSend implements Runnable{ DatagramSocket socket=null; BufferedReader reader=null; private int fromPort; private String toIp; private int toPort; public TalkSend(int fromPort, String toIp, int toPort) { this.fromPort = fromPort; this.toIp = toIp; this.toPort = toPort; try { socket=new DatagramSocket(fromPort); reader=new BufferedReader(new InputStreamReader(System.in)); }catch (Exception e){ e.printStackTrace(); } } @Override public void run() { while (true){ try { String data = reader.readLine(); byte[] datas=data.getBytes(); DatagramPacket packet=new DatagramPacket(datas,0,datas.length,new InetSocketAddress(this.toIp,this.toPort)); socket.send(packet); if (data.equals("bye")){ System.exit(0); break; } } catch (IOException e) { e.printStackTrace(); } } socket.close(); } }
-
接收端
public class TalkReceive implements Runnable{ DatagramSocket socket=null; BufferedReader reader=null; private int Port; private String msgForm; public TalkReceive( int port,String msgForm) { Port = port; this.msgForm = msgForm; try{ socket=new DatagramSocket(port); }catch (Exception e){ e.printStackTrace(); } } @Override public void run() { try { while (true) { //准备接收包裹 byte[] buffer = new byte[1024]; DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length); socket.receive(packet);//阻塞接收包裹 //断开连接 byte byte[] date = packet.getData(); String receiveDate = new String(date, 0, date.length); System.out.println(msgForm + ":"+receiveDate); if (receiveDate.equals("bye")) { System.exit(0); break; } } } catch (IOException e) { e.printStackTrace(); } socket.close(); } }
-
主程序
public class TalkTeacher{ public static void main(String[] args) { new Thread(new TalkSend(5555,"localhost",8888)).start(); new Thread(new TalkReceive(9999, "学生")).start(); } }
public class TalkStudent{ public static void main(String[] args) { new Thread(new TalkSend(7777,"localhost",9999)).start(); new Thread(new TalkReceive(8888, "老师")).start(); } }
-
-
9.URL
-
https://www.baidu.com
-
统一资源定位符:定位资源的,定位互联网上的某一个资源
-
DNS 域名解析 www.baidu.com xxx.x…x…x
-
协议://ip地址:端口|项目名|资源
public class URLDemo { public static void main(String[] args) throws Exception { URL url= new URL("http://localhost:8080/helloworld/index.jsp?username=aa&password=123"); System.out.println(url.getProtocol());//协议 System.out.println(url.getHost());//主机IP System.out.println(url.getPort());//端口 System.out.println(url.getPath());//文件 System.out.println(url.getFile());//全路径 System.out.println(url.getQuery());//参数 } }
-
从网上下载文件(图片、音乐等)
public class URLDome2 { public static void main(String[] args) throws Exception { //1.下载地址 URL url= new URL("https://y.gtimg.cn/music/photo_new/T002R300x300M000001WEt7b1iMdIJ_1.jpg?max_age=2592000"); //2.连接到这个资源 HTTP HttpURLConnection urlConnection=(HttpURLConnection)url.openConnection(); InputStream inputStream=urlConnection.getInputStream(); FileOutputStream fos=new FileOutputStream("T002R300x300M000001WEt7b1iMdIJ_1.jpg"); byte[] buffer=new byte[1024]; int len; while ((len=inputStream.read(buffer))!=-1){ fos.write(buffer,0,len);//写出这个数据 } fos.close(); inputStream.close(); urlConnection.disconnect();//断开连接 } }