一 、什么是计算机网络
计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。
1 网络编程的目的
实现传播交流信息,数据交换、通信
2 如何确定网络上的一台主机
IP地址 + port 定位到这台计算机的某个资源
eg:192.168.16.124:8080
二 、网络通信要素
1 、 通信双方地址 : IP + port
2 、 网络通信的协议
TCP/IP参考模型
我们这篇博客主要是针对传输层
三 、IP
IP地址 :InetAddress
-
唯一定位一台计算机
-
127.0.0.1 /localhost 本机地址
-
ip地址分类
1 、 ipv4 : 四个字节组成(1byte = 8bit),每个字节的范围是0 - 255 (1X27+1X26+1X25+1X24+1X23+lX22+1 X21+1X20=255);ipv4一共有42亿,但是30亿都在北美,亚洲4亿,2011年就用完了,所以有了IPV6
2、IPV6 : 128位,8位无符号整数
eg ; 2001 :obba :1284:0000:0000:1aaa:2aaa:1524 -
公网 (互联网)、私网(局域网)
* ABCD 类地址 * 192.168.XX.xx 专门给组织内部使用
-
域名:解决IP记忆问题
与IP相关的类 InetAddress
package intentp;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class testInternrt {
public static void main(String[] args) {
try {
//查询ip地址
InetAddress address = InetAddress.getByName("127.0.0.1");
InetAddress address1 = InetAddress.getByName("www.baidu.com");
InetAddress localHost = InetAddress.getLocalHost();
System.out.println(address1);
System.out.println(address);
System.out.println(localHost);
System.out.println(InetAddress.getAllByName("127.0.0.1"));
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
四 端口port
我们可以将端口理解为表示计算机上的一个进程
* 不同的进程有不同的端口号!
* 被规定:0 ——65535
* TCP/ UDP :65535 * 2 单个协议下端口号不能相同
* 端口分类
** 共有端口0-1023
** HTTP :80(默认端口)
** HTTPS :443 (默认端口)
** FTP: 21
** Telent : 23
* 程序注册端口:1024-49151
* Tomcat 8080
* Mysql 3306
* Oracle : 1521
* 动态私有 : 49152 - 65535
*关于端口常见的dos命令
* netstat -ano 查看所有的端口
* netstat -ano |findstr "port" 查找指定的端口
* tasklist|findstr "port“ 查看指定端口的进程
* taskkill -pid 进程号 -f 杀死端进程
* ctr + shift +esc 打开任务管理器
package intentp;
import java.net.InetSocketAddress;
/**
*C:\Windows\System32\drivers\etc 里面的host文件可以配置本机的映射地址
* 127.0.0.1 www.sso.com
*/
public class InetSocketAddressTest {
public static void main(String[] args) {
InetSocketAddress socketAddress = new InetSocketAddress("localhost", 8080);
InetSocketAddress socketAddress2 = new InetSocketAddress("127.0.0.1", 8080);
System.out.println(socketAddress);
System.out.println(socketAddress2);
System.out.println(socketAddress.getAddress());
System.out.println(socketAddress.getHostName());
System.out.println(socketAddress.getPort());
}
}
这里给大家说一下如何配置本机地址的映射
打开我的电脑——》C盘——》System32——》drivers——》etc 找到host文件,在里面添加映射就可以了
五 、通信协议
协议:可以理解为一种约定,约定以双方能懂的方式进行交流
TCP/IP协议簇
- TCP : 用户传输协议
- UDP : 用户数据协议报
TCP/UDP对比
TCP :- 连接、稳定
- 三次握手
- 四次挥手
- 客户端 、服务端
- 传输完成、释放连接、效率低
UDP:
- 不连接、不稳定
- 客户端、服务端 没有明确的界限
- 不管有没有准备好都可以发送给你
- 比如:DDOS 洪水攻击
TCP实现聊天
TCP实现客户端和服务端之间的通信
package intentp;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
/**
* TCP: 实现聊天
* client:
* server:
*
*/
//客户端
public class TcpClientDemo {
public static void main(String[] args) {
Socket socket = null;
OutputStream os = null;
try {
//要知道服务器的地址
InetAddress serverip = InetAddress.getByName("127.0.0.1");
int port = 9999;
//传建一个scoket连接
socket = new Socket(serverip,port);
//发消息
os = socket.getOutputStream();
os.write("你好服务器".getBytes());
} catch (Exception e) {
e.printStackTrace();
}finally {
if (os != null){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
package intentp;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
//服务端
public class TcpServerDemo {
public static void main(String[] args) {
ServerSocket serverSocket = null;
Socket accept = null;
InputStream inputStream = null;
ByteArrayOutputStream baos = null;
try {
// 有一个地址
serverSocket = new ServerSocket(9999);
//等待客户端连接
accept = serverSocket.accept();
//接收消息
inputStream = accept.getInputStream();
/*
//这样写 万一内容超过1024就容易断开
byte[] bytes = new byte[1024];
int len ;
while((len = inputStream.read(bytes)) != -1){
String s = new String(bytes, 0, len);
System.out.println(s);
}*/
baos = new ByteArrayOutputStream();
byte[] bytes = new byte[1024];
int len;
while ((len = inputStream.read(bytes)) != -1){
baos.write(bytes,0,len);
}
System.out.println(baos.toString());
} catch (IOException e) {
e.printStackTrace();
}finally {
if (baos != null){
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (inputStream != null){
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (accept != null){
try {
accept.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (serverSocket != null){
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
TCP实现文件传输
package intentp;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
/**
* TCP文件上传
*
*/
public class TcpFileClientDemo {
public static void main(String[] args) throws Exception{
//创建一个socket连接
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9000);
//创建一个输出流
OutputStream os = socket.getOutputStream();
//文件流
FileInputStream fileInputStream = new FileInputStream(new File("class2.png"));
byte[] bytes = new byte[1024];
int len = 0;
while((len=fileInputStream.read(bytes)) != -1){
os.write(bytes,0,len);
}
//通知服务器我已经结束了
socket.shutdownOutput();//我已经传输完了
//确定服务器接收完毕
InputStream iss = socket.getInputStream();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while ((len = iss.read(bytes)) != -1){
bos.write(bytes,0,len);
}
System.out.println(bos.toString());
//关闭资源
bos.close();
iss.close();
fileInputStream.close();
os.close();
socket.close();
}
}
package intentp;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
/**
* TCP 传输文件服务器端
*/
public class TcpFileServerDemo {
public static void main(String[] args) throws Exception{
//建立一个地址--->创建服务
ServerSocket socket = new ServerSocket(9000);
//等待连接------》监听服务(阻塞监听)
Socket accept = socket.accept();
//接收消息
InputStream is = accept.getInputStream();
FileOutputStream fos = new FileOutputStream(new File("receive.png"));
byte[] bytes = new byte[1024];
int len;
while((len = is.read(bytes)) != -1){
fos.write(bytes,0,len);
}
//通知客户端我接受完了
OutputStream oss = accept.getOutputStream();
oss.write("我接收完了,你可以断开了".getBytes());
oss.close();
fos.close();
is.close();
accept.close();
socket.close();
}
}
UDP消息发送
package intentp;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/**
* Tomcat 完全由java写的
* UDP 不用连接 服务器
* 建立socket
* 建立一个包
* 发送包
* 主要方法 data报包
*
*/
public class UdpClientDemo {
public static void main(String[] args) throws Exception {
//建立socket
DatagramSocket socket = new DatagramSocket(9090);
//建立一个包 //发送给谁 //发送什么
String mssage = "我是UDP不建立连接";
InetAddress localhost = InetAddress.getByName("localhost");
int port = 9090;
DatagramPacket packet = new DatagramPacket(mssage.getBytes(),0,mssage.getBytes().length,localhost,port);
//发送包
socket.send(packet);
//关闭资源
socket.close();
}
}
UDP中客户端和服务端没有明确的界限
package intentp;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
/**
* UDP 没有真正的client 和server 概念
* 还是要等待客户端的连接
*/
public class UdpServerDemo {
public static void main(String[] args) throws Exception{
//开放端口
DatagramSocket socket = new DatagramSocket(9090);
//接收数据
byte[] bytes = new byte[1024];
//接到哪里
DatagramPacket packet = new DatagramPacket(bytes, 0, bytes.length);
socket.receive(packet);
System.out.println(packet.getAddress().getHostAddress());
System.out.println(new String(packet.getData(),0,packet.getLength()));
socket.close();
}
}
UDP实现聊天
package chat;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
public class UdpSendDemo {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket(8888);
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
while (true){
String s = reader.readLine();
byte[] bytes = s.getBytes();
//建立一个包 //发送给谁 //发送什么
DatagramPacket packet = new DatagramPacket(bytes, 0, bytes.length,new InetSocketAddress("localhost",6666));
socket.send(packet);
if (bytes.equals("bye")){
break;
}
}
socket.close();
}
}
package chat;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class UdpResceiveDemo {
public static void main(String[] args) throws Exception{
DatagramSocket socket = new DatagramSocket(6666);
while (true){
byte[] bytes = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(bytes, 0, bytes.length);
socket.receive(datagramPacket);
byte[] data = datagramPacket.getData();
String s = new String(data, 0, data.length);
System.out.println(s);
if (s.equals("bye")){
break;
}
}
socket.close();
}
}
UDP多线程在线咨询
TALKSEND(消息发送者)
package chat;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
public class TalkSened implements Runnable {
DatagramSocket socket = null;
BufferedReader reader = null;
private String toIp;
private int toProt;
private int fromProt;
public TalkSened(String toIp, int toProt, int fromProt) {
this.toIp = toIp;
this.toProt = toProt;
this.fromProt = fromProt;
try {
socket = new DatagramSocket(this.fromProt);
reader = new BufferedReader(new InputStreamReader(System.in));
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while (true){
String s = null;
try {
s = reader.readLine();
byte[] bytes = s.getBytes();
DatagramPacket packet = new DatagramPacket(bytes, 0, bytes.length,new InetSocketAddress(this.toIp,this.toProt));
socket.send(packet);
if (bytes.equals("bye")){
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
socket.close();
}
}
TALKRECEVIE(消息接收者)
package chat;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class TalkReceive implements Runnable {
DatagramSocket socket = null;
private int fromProt;
private String fromMessge;
public TalkReceive(int fromProt,String fromMessge) {
this.fromProt = fromProt;
this.fromMessge = fromMessge;
try {
socket = new DatagramSocket(this.fromProt);
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while (true){
try {
byte[] bytes = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(bytes, 0, bytes.length);
socket.receive(datagramPacket);
byte[] data = datagramPacket.getData();
String s = new String(data, 0, data.length);
System.out.println(fromMessge+":"+ s);
if (s.equals("bye")){
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
socket.close();
}
}
学生
package chat;
public class TalkStudent {
public static void main(String[] args) {
TalkSened talkSened = new TalkSened("localhost", 9999, 7777);
TalkReceive talkReceive = new TalkReceive(8888, "老师");
new Thread(talkSened).start();
new Thread(talkReceive).start();
}
}
老师
package chat;
public class TalkTeacher {
public static void main(String[] args) {
TalkSened talkSened = new TalkSened("localhost", 8888, 5555);
TalkReceive talkReceive = new TalkReceive(9999, "学生");
new Thread(talkSened).start();
new Thread(talkReceive).start();
}
}
URL下载网络资源
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
public class Url {
public static void main(String[] args) throws Exception {
URL url = new URL("https://www.baidu/XXXX);//这里写下载资源的网络地址
//连接到这个资源
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
InputStream inputStream = urlConnection.getInputStream();
FileOutputStream fos = new FileOutputStream("f.m4a");
byte[] bytes = new byte[1024];
int len;
while ((len = inputStream.read(bytes)) != -1){
fos.write(bytes,0,len);
}
fos.close();
inputStream.close();
urlConnection.disconnect();
}
}