IP地址: IP地址是我们电脑在网络中的唯一标记, 所有的电脑之间进行信息交互都是利用这个IP地址来进行识别。
端口号: ip地址唯一标示了通信实体,但是一个通信实体可以有多个通信程序同时提供网络服务。这个时候就要通过端口来区分开具体的通信程序。一个通信实体上不能有两个通信程序使用同一个端口号。
TCP/IP协议: IP协议规定了我们网络当中的每一台PC的唯一标记,TCP协议就规定数据传输的编码和解码的格式。网卡就是根据TCP/IP协议生产的不见,为电脑生产IP地址,组装TCP协议,都是由网卡完成。
UDP: 用户数据报协议,UDP是一种无连接的协议,每个数据报都是一个独立的信息,包括完整的源地址或目的地址,它在网络上以任何可能的路径传送目的地,至于能够达到目的地,达到目的地的时间以及内容的正确性都是不能保证的。
Telnet: Internet远程登录服务的标准协议和主要方式。
FTP: 文本传输协议。
HTTP: 超文本传送协议。是互联网上应用最为广泛的一种网络协议,是一个基于TCP和UDP的高级协议,主要用于网络之间数据传输,我们的web项目全是使用该协议。
HTTPS: 是以安全为目标的HTTP通道,简单讲是HTTP的安全版,即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。
URL:
1、URL对象代表统一资源定位器,是指向互联网“资源”的指针。它是用协议名、主机、端口和资源组成,即满足如下格式:
protocol://host:port/resourceName
http://www.xxxxx.com/index.jsp
2、通过URL对象的一些方法可以访问该URL对应的资源:
String getFile():获取该URL的资源名
String getHost():获取主机名
String getPath():获取路径部分
int getPort():获取端口号
3、通过URL获取数据并利用线程下载
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Date;
public class Test {
public static void main(String[] args) {
//获取网络资源 https://www.baidu.com/img/bd_logo1.png
// System.out.println(connection.getContentLength());
// 10 * 1024 / 10 == 10个线程,每一个读一段
try {
URL url = new URL("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1529561868526&di=fc4ed55264363524350598bb67f6c989&imgtype=0&src=http%3A%2F%2Fimg.zcool.cn%2Fcommunity%2F0114375543f8ec0000019ae948310f.jpg");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//未来我们就利用connection 去获取数据
System.out.println(connection.getContentLength());
byte b[] = new byte[8000];
InputStream is = connection.getInputStream();
long time = new Date().getTime();
//注意,服务器给数据是按照他的规则给 每次很少, 所以我们循环获取数据
while(true){
int num = is.read(b); //num = 读取数据的长度
//当读取到的数据为-1的时候,就表示没有数据
if(num==-1) {
break;
}else{
System.out.println("本次下载长苏:" + num + "字节");
FileOutputStream fos = new FileOutputStream("e:/a.png",true);
//由于每次读取的数据有效,我们不要吧整个byte数组写到硬盘, 而是要写入里面获取到的数据。
fos.write(b, 0, num);
fos.close();
}
}
long time1 = new Date().getTime();
System.out.println(time1- time);
} catch (Exception e) {
e.printStackTrace();
}
}
}
如果说需要使用多线程下载,会出现一个问题,线程的先后顺序不一致,导致存储数据时可能错位,所以我们需要使用一个能制定数据存在到那个位置的流,这个流就是RandomAccessFile
package com.test.down;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;
public class DownLoad implements Runnable{
public int start;
public int end;
public String urlStr;
public int point;
public DownLoad(int start, int end, String urlStr) {
this.start = start;
this.end = end;
this.urlStr = urlStr;
this.point = start;
}
public void run() {
try {
URL url = new URL(urlStr);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//未来我们就利用connection 去获取数据
//设置读取的长度??
connection.setAllowUserInteraction(true); //设置读取点
connection.setRequestProperty("Range", "bytes=" + start + "-" + end);
connection.connect();
byte b[] = new byte[8000];
InputStream is = connection.getInputStream();
long time = new Date().getTime();
//注意,服务器给数据是按照他的规则给 每次很少, 所以我们循环获取数据
while(true){
int num = is.read(b); //num = 读取数据的长度
//当读取到的数据为-1的时候,就表示没有数据
if(num==-1) {
break;
}else{
System.out.println("本次下载长度:" + num + "字节");
RandomAccessFile random = new RandomAccessFile("d:/b.jpg","rw");
//设置存放点
random.seek(point);
random.write(b, 0, num);
point += num;
random.close();
}
}
long time1 = new Date().getTime();
// System.out.println(time1- time);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Socket:
Socket又称套接字,是连接运行在网络上两个程序间的双向通讯的端点。
服务端:服务器程序将一个套接字绑定到一个特定的端口,并通过此套接字等待和监听客户端的连接请求。
客户端:客户端程序根据你服务器所在的主机名和端口号发出连接请求。
服务端和客户端两者之间的通信是通过Socket完成的。
1.创建简单的服务端、客户端
服务器端:
public static void main(String[] args) throws IOException
{
//创建一个ServerSocket,用于监听客户端Socket连接请求
ServerSocket ss = new ServerSocket(8888);
System.out.println("server start");
//采用循环方式监听客户端的请求
while(true)
{
//侦听并接受到此套接字的连接。此方法在连接传入之前一直阻塞。
Socket socket = ss.accept();
OutputStream os = socket.getOutputStream();
PrintStream ps = new PrintStream(os);
ps.print("服务端的信息");
ps.close();
os.close();
socket.close();
}
}
客户端:
public static void main(String[] args) throws IOException, Exception
{
Socket socket = new Socket("localhost",8888);
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String str = br.readLine();
System.out.println(str);
br.close();
is.close();
socket.close();
}
2.整合多线程实现 及时聊天通信
一个读数据线程,一个写数据线程
写数据
package com.test.client;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;
public class WriteThread implements Runnable{
Socket socket;
public WriteThread( Socket s) {
this.socket = s;
}
public void run() {
try {
OutputStream os = socket.getOutputStream();
Scanner sc = new Scanner(System.in);
while(true) {
String word = sc.nextLine();
byte b[] = word.getBytes();
os.write(b);
os.flush();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
读数据
package com.test.client;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
public class ReadThread implements Runnable{
private Socket socket;
public String name;
public ReadThread( Socket s, String name){
this.socket = s;
this.name = name;
}
public void run() {
try {
InputStream in = socket.getInputStream();
byte b[] = new byte[1024];
while(true) {
in.read(b);
String word = new String(b);
System.out.println(name + "说:" + word);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
客户端
package com.test.client;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
public Client() {
init();
}
public void init() {
try {
Socket s = new Socket("127.0.0.1", 9999);
//启动读线程
new Thread(new ReadThread(s,"服务器")).start();
//启动写线程
new Thread(new WriteThread(s)).start();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
new Client();
}
}
服务端
package com.test.client;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public Server() {
try {
ServerSocket server = new ServerSocket(9999);
Socket s = server.accept();
//启动读线程
new Thread(new ReadThread(s, "客户端")).start();
//启动写线程
new Thread(new WriteThread(s)).start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
new Server();
}
}
3.DataGramSocket:注意和TCP IP的区别 DataGramSocket 既是服务器又是客户端。
客户端
package com.test.udp;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
//客户端
public class TestClient {
public static void main(String[] args) {
try {
DatagramSocket server = new DatagramSocket(8888);
byte b[] = new byte[1024];
DatagramPacket packet = new DatagramPacket(b, b.length);
server.receive(packet);
System.out.println("over" + new String(b));
//将数据存储到硬盘上
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
服务器
package com.test.udp;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
//服务器
public class TestServer {
public static void main(String[] args) {
try {
DatagramSocket server = new DatagramSocket();
byte buff[] = new byte[1024];
buff = "zhangsan".getBytes();
InetAddress ip = InetAddress.getByName("127.0.0.1");
DatagramPacket packet = new DatagramPacket(buff, buff.length,ip,8888);
server.send(packet);
server.close();
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}