网络编程
网络编程
解决单元测试的时候控制台不可以输入的问题:
1.找到idea安装目录bin下的idea.exe.vmoptions和idea64.exe.vmoptions
2.在这两个文件最后加入一行 -Deditable.java.test.console=true 就ok了
计算机网络:
计算机网络是将地理位置不同的,具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统、网络管理软件以及网络通信协议的协调和管理下,实现资源共享和信息传递。
javaweb编程是B/S架构
java网络编程是C/S架构
计算机网络的两个核心要素
IP+端口号
IP地址:java类 InetAddress
特殊的ip:127.0.0.1 本机(localhost)
分类:
1、 IP地址分类(IPV4 IPV6)
IPV4:由四个字节组成(32位),大概有42亿 其中30亿在北美,亚洲只有四亿
IPV6: 128位(十六个字节)
2、 公网(互联网)---私网(局域网)
192.168.0.0到192.168.255.255 比较大的私网,给专门的机构使用
ABCD类地址:
域名:方便对ip的记忆,其实就是ip地址的另一种表现形式
import java.net.InetAddress;
import java.net.UnknownHostException;
public class FileUtilsTest {
public static void main(String[] args) {
try {
//InetAddress实例化方法(构造器私有化了,不可以通过构造器进行实例化)
InetAddress inetAddress1=InetAddress.getByName("www.bilibili.com");
InetAddress inetAddress2=InetAddress.getByName("112.45.120.2");
InetAddress inetAddress3=InetAddress.getLocalHost();
//一般情况下输出inetAddress1会慢一点,因为要解析这个域名,并且一般是通过DNS服务器进行解析
System.out.println(inetAddress1);
System.out.println(inetAddress2);
System.out.println(inetAddress3);
//常用方法
System.out.println(inetAddress1.getHostName());//获取主机名或者域名
System.out.println(inetAddress1.getHostAddress());//获取主机ip
System.out.println(inetAddress1.getCanonicalHostName());//获取规范化的主机名或者ip
System.out.println(inetAddress3.getCanonicalHostName());
System.out.println(inetAddress2.getCanonicalHostName());
}catch (UnknownHostException e){
e.printStackTrace();
}
}
}
端口:每一个端口都对应着一个进程
被规定为0-65535
公认端口(0~1023):
HTTP:80
HTTPS:43
FTP:21
Telent:23
注册端口:1024-49151
Tomcat:8080
Mysql:3306
Oracle:1521
动态、私有:19152-65535
Netstat -ano//查看所有端口
Netstat -ano|findstr “要查询的端口” |:过滤符号
Tasklist|findstr “要查询的端口” 查看进程名
端口号和ip组合得出一个网络套接字:Socket
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class FileUtilsTest {
public static void main(String[] args) {
InetSocketAddress inetSocketAddress1=new InetSocketAddress("127.0.0.1",8080);
InetSocketAddress inetSocketAddress2=new InetSocketAddress("localhost",8080);
System.out.println(inetSocketAddress1.getAddress());//ip地址
System.out.println(inetSocketAddress1.getPort());//端口号
System.out.println(inetSocketAddress1.getHostName());//主机名或者域名
}
}
C:\Windows\System32\drivers\etc\hosts文件是本机的域名解析文件,当浏览器访问域名的时候,先在这个文件中查找ip,如果找不到再去DNS服务器进行解析。
网络通信协议(对速率、传输代码、代码结构、传输控制步骤、出错控制等制定的标准)
OSI参考模型:过于理想化,未能在因特网上广泛推广
TCP/IP参考模型:事实上的国际标准

不可以隔层通信。
TCP:传输控制协议
UDP:用户数据报协议
TCP/IP协议簇有两个主要协议,一个是传输层的TCP协议,一个是网络层的IP协议。
TCP:
使用TCP协议前,要建立TCP连接(三次握手),创建出传输数据通道
TCP协议进行通信的两个应用进程:客户端、服务端
传输完毕后,需要释放建立的传输数据通道(四次挥手)
三次握手:
TCP报文:

32位序号就是seq
32位确认序号就是ack(对上一次发送来的报文表示确认的序号)
六个标志位
URG
ACK:确认标志位
PSH
RST
SYN:发起一个新的连接(1)
FIN:结束一个连接(1)

此时的x、y、z是随机的。传输的时候就不是了!
为啥z不是x+1?
为什么要三次才可以建立连接:因为三次是服务端和客户端互相确认可以收到消息 最少的次数。
四次挥手:
一般是客户端请求断开连接,但是服务端也能请求断开连接。

为啥要四次才能断开连接:因为请求方请求断开连接的时候,很有可能被断开方来不及释放socket资源,所以要进行确认。
import org.junit.Test;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class TCPTest {
@Test
public void clientTest(){
Socket socket=null;
OutputStream outputStream=null;
try {
InetAddress inetAddress=InetAddress.getByName("127.0.0.1");
socket=new Socket(inetAddress,8899);
outputStream=socket.getOutputStream();
Scanner scanner=new Scanner(System.in);
while(true){
String str=scanner.nextLine();
if("exit".equalsIgnoreCase(str)){
socket.shutdownOutput();
break;
}
outputStream.write(str.getBytes());
}
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if(outputStream!=null){
outputStream.close();
}
if(socket!=null){
socket.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
@Test
public void serverTest(){
ServerSocket serverSocket=null;
InputStream inputStream=null;
//InputStreamReader inputStreamReader=null;
ByteArrayOutputStream byteArrayOutputStream=null;
try {
serverSocket=new ServerSocket(8899);
while(true){
Socket socket=serverSocket.accept();//阻塞式监听
inputStream=socket.getInputStream();
/* inputStreamReader=new InputStreamReader(inputStream,"utf-8");
int len=-1;
while((len=inputStreamReader.read())!=-1){
System.out.println((char)len);
}*/
byteArrayOutputStream=new ByteArrayOutputStream();
byte[] bytes=new byte[10];
int len=-1;
while((len=inputStream.read(bytes))!=-1){
//System.out.println(new String(bytes,0,len));
byteArrayOutputStream.write(bytes,0,len);
}
System.out.println(byteArrayOutputStream.toString());
}
}catch (Exception e){
e.printStackTrace();
}finally {
try {
/*if(inputStreamReader!=null){
inputStreamReader.close();
}*/
if(byteArrayOutputStream!=null){
byteArrayOutputStream.close();
}
if(serverSocket!=null){
serverSocket.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
import org.junit.Test;
import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class TCPTest {
@Test
public void clientTest(){
Socket socket=null;
OutputStream outputStream=null;
InputStream inputStream=null;
InputStreamReader inputStreamReader=null;
try {
InetAddress inetAddress=InetAddress.getByName("127.0.0.1");
socket=new Socket(inetAddress,8899);
outputStream=socket.getOutputStream();
byte[] buff=new byte[10];
int len=-1;
FileInputStream fileInputStream=new FileInputStream("C:\\Users\\26779\\Desktop\\老婆.jpg");
while((len=fileInputStream.read(buff))!=-1){
outputStream.write(buff,0,len);
}
fileInputStream.close();
socket.shutdownOutput();
inputStream=socket.getInputStream();
inputStreamReader=new InputStreamReader(inputStream);
int data=-1;
while((data=inputStreamReader.read())!=-1){
System.out.print((char)data);
}
System.out.println();
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if(inputStreamReader!=null){
inputStreamReader.close();
}
if(outputStream!=null){
outputStream.close();
}
if(socket!=null){
socket.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
@Test
public void serverTest(){
ServerSocket serverSocket=null;
InputStream inputStream=null;
OutputStream outputStream=null;
try {
serverSocket=new ServerSocket(8899);
Socket socket=serverSocket.accept();//阻塞式监听
inputStream=socket.getInputStream();
byte[] bytes=new byte[10];
int len=-1;
FileOutputStream fileOutputStream=new FileOutputStream("C:\\Users\\26779\\Desktop\\老婆1.jpg");
while((len=inputStream.read(bytes))!=-1) {
fileOutputStream.write(bytes, 0, len);
}
fileOutputStream.close();
outputStream=socket.getOutputStream();
outputStream.write("结束".getBytes());
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if(outputStream!=null){
outputStream.close();
}
if(serverSocket!=null){
serverSocket.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
UDP:
将数据、源、目的都封装成为数据报,不需要建立连接
每个数据报大小限制为64k
发送时不管对方是否准备好的,接收方也没有确认收到的机制
可以进行广播
传输结束无需释放资源
UDP实现聊天:
Receiver:
package com.geng.talk;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class Receiver implements Runnable{
private int fromPort;
DatagramPacket datagramPacket;
DatagramSocket datagramSocket;
public Receiver(int fromPort) {
this.fromPort = fromPort;
try{
datagramSocket=new DatagramSocket(fromPort);
byte[] data=new byte[1024];
datagramPacket=new DatagramPacket(data,0,data.length);
}
catch (Exception e){
e.printStackTrace();
}
}
@Override
public void run() {
try{
while(true){
datagramSocket.receive(datagramPacket);
String str=new String(datagramPacket.getData(),0,datagramPacket.getData().length);
System.out.println("IP: "+datagramPacket.getAddress()+" 端口号: "+datagramPacket.getPort()
+": "+str);
if("#end".equals(str)){
break;
}
}
datagramSocket.close();
}
catch (Exception e){
e.printStackTrace();
}
}
}
Sender:
package com.geng.talk;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
public class Sender implements Runnable{
private int toPort;
private int selfPort;
private String toIp;
private DatagramSocket datagramSocket;
private DatagramPacket datagramPacket;
private BufferedReader cin;
public Sender(int toPort, int selfPort, String toIp) {
this.toPort = toPort;
this.selfPort = selfPort;
this.toIp = toIp;
cin=new BufferedReader(new InputStreamReader(System.in));
try{
datagramSocket=new DatagramSocket(this.selfPort);
}
catch (Exception e){
e.printStackTrace();
}
}
@Override
public void run(){
try{
while(true){
String str=cin.readLine();
datagramPacket=new
DatagramPacket(str.getBytes()
,0,str.getBytes().length,new InetSocketAddress(this.toIp,this.toPort));
datagramSocket.send(datagramPacket);
if("#end".equals(str)){
break;
}
}
datagramSocket.close();
}
catch (Exception e){
e.printStackTrace();
}
}
}
Teacher:
package com.geng.talk;
public class Teacher {
public static void main(String[] args){
new Thread(new Receiver(9090)).start();
new Thread(new Sender(9999,6666,"localhost")).start();
}
}
Student:
package com.geng.talk;
public class Student {
public static void main(String[] args){
new Thread(new Receiver(9999)).start();
new Thread(new Sender(9090,5555,"localhost")).start();
}
}
URL:统一资源定位符
表示Internet上面的某一个资源的地址
URL由五部分组成:
<传输协议>://<主机名(域名)(ip)>:<端口号>/<文件名>#片段名?参数列表
@Test
public void test01(){
try {
URL url=new URL("http://localhost:8080/springmvc/index.jsp?password=123&name=geng");
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());//获取参数列表
}catch (MalformedURLException e){
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
//创建一个url
URL url=new URL("http://www.cnpaf.net/Class/HTTP/200811/23277.html");
//打开这个url(打开这个资源)
HttpURLConnection httpURLConnection=(HttpURLConnection)url.openConnection();
InputStream inputStream=httpURLConnection.getInputStream();
FileOutputStream fileOutputStream=new FileOutputStream("f.m4a");
byte[] buffer=new byte[1024];
int len;
while((len=inputStream.read(buffer))!=-1){
fileOutputStream.write(buffer,0,buffer.length);
}
fileOutputStream.close();
inputStream.close();
httpURLConnection.disconnect();
}
浙公网安备 33010602011771号