网络编程
计算机网络:将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统、网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。
-
如何准确的定位网络上的一台主机
-
如何传输数据
Java web:网页编程 B/S
网络编程:TCP/IP C/S
1.网络通信的两个要素
如何实现网络的通信?
-
通信双方地址: IP和端口号
-
规则:网络通信的协议:OSI七层网络模型、TCP/IP四层概念模型。
2.IP
localhost:127.0.01 本机
IP地址分类:
-
ipv4/ipv6
-
公网-私网(局域网)
域网:形如www.baidu.com
package com.lesson;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class TestInetAddress {
public static void main(String[] args) throws UnknownHostException {
//查询本地地址
InetAddress inetAddress1=InetAddress.getByName("127.0.0.1");
System.out.println(inetAddress1);
InetAddress inetAddress3=InetAddress.getByName("localhost");
System.out.println(inetAddress3);
InetAddress inetAddress4=InetAddress.getLocalHost();
System.out.println(inetAddress4);
//查询网站IP地址
InetAddress inetAddress2=InetAddress.getByName("www.baidu.com");
System.out.println(inetAddress2);
//常用方法,以下都不常用
//System.out.println(inetAddress2.getAddress());//地址
System.out.println(inetAddress2.getCanonicalHostName());//IP
System.out.println(inetAddress2.getHostAddress());//IP
System.out.println(inetAddress2.getHostName());//域名,或本地电脑名
}
}
3.端口
TCP或UDP:单个协议下端口号不能冲突。
端口分类:
共用端口:0-1023
程序注册端口:2014-49151,分配给用户或程序。如Tomcat:8080
动态、私有:49152-65535
netstat -ano//查看所有端口 netstat -ano|findstr "5900"//查看指定端口 tasklist|findstr "8696"//查看指定端口的进程
4.通信协议
网络通信协议:速率,传输码率,代码结构,传输控制……
TCP/IP协议簇:TCP(用户传输协议),UDP(用户数据报协议)
两者的区别:TCP三次握手、四次挥手,连接稳定,有客户端和服务端,形如打电话;UDP不连接不稳定,客户端服务端没有明确界限,形如发电报。
5.TCP
使用Socket传输消息:
客户端:
package com.lesson;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
public class TestClientDemo {
public static void main(String[] args) throws IOException {
//获取服务器地址及端口号
InetAddress serverIP=InetAddress.getByName("127.0.0.1");
int port=9999;
//创建socket连接
Socket socket = new Socket(serverIP, port);
//发送消息
OutputStream os = socket.getOutputStream();
os.write("数据".getBytes());
socket.close();
}
}
服务端:
package com.lesson;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TestServerDemo {
public static void main(String[] args) throws IOException {
//生成端口号地址
ServerSocket serverSocket = new ServerSocket(9999);
//等待客户端连接
Socket socket = serverSocket.accept();
//读取客户端消息
InputStream is = socket.getInputStream();
//管道流
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer=new byte[1024];
int len;
while ((len=is.read(buffer))!=-1){
baos.write(buffer,0,len);
}
System.out.println(baos.toString());
//关闭资源,谁先连接谁先断开
baos.close();
is.close();
socket.close();
serverSocket.close();
}
}
先运行服务端再运行客户端。
使用Socket传输文件:
客户端:
package com.lesson;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class ClientDemo {
public static void main(String[] args) throws IOException {
//创建socket连接
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9000);
//创建输出流
OutputStream os = socket.getOutputStream();
//读取文件
FileInputStream fis = new FileInputStream(new File("1.jpg"));
//写出文件
byte[] buffer = new byte[1024];
int len;
while ((len= fis.read(buffer))!=-1){
os.write(buffer,0,len);
}
//关闭资源
fis.close();
os.close();
socket.close();
}
}
服务端:
package com.lesson;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerDemo {
public static void main(String[] args) throws IOException {
//创建服务->端口
ServerSocket serverSocket = new ServerSocket(9000);
//监听客户端连接
Socket socket = serverSocket.accept();//阻塞式监听,会一直等待客户端连接
//获取输入流
InputStream is = socket.getInputStream();
//输出文件
FileOutputStream fos = new FileOutputStream(new File("receive.jpg"));
byte[] buffer = new byte[1024];
int len;
while ((len=is.read(buffer))!=-1){
fos.write(buffer,0,len);
}
//关闭资源
fos.close();
is.close();
socket.close();
serverSocket.close();
}
}
6.UDP
客户端:
package com.lesson;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;
//不需要连接服务器
public class TestUdpDemo {
public static void main(String[] args) throws Exception {
//建立Socket
DatagramSocket socket = new DatagramSocket();
//建立包
String msg="你好";
//发送对象
InetAddress localhost=InetAddress.getByName("localhost");
int port=9090;
//数据传输
DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length,localhost,port);
//发送包
socket.send(packet);
//关闭流
socket.close();
}
}
服务端:
package com.lesson;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
//服务器端
public class TestUdpServerDemo {
public static void main(String[] args) throws Exception {
//开放端口
DatagramSocket socket = new DatagramSocket(9090);
//接收数据包
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
socket.receive(packet);
System.out.println(new String(packet.getData(),0,packet.getLength()));
//关闭连接
socket.close();
}
}
实时聊天(不太行):
package com.lesson.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 ChatSend implements Runnable{
DatagramSocket socket=null;
BufferedReader reader=null;
private String toIP;
private int fromPort;
private int toPort;
public ChatSend(int fromPort,String toIP,int toPort) throws Exception {
this.fromPort = fromPort;
this.toIP = toIP;
this.toPort = toPort;
socket = new DatagramSocket(fromPort);
reader = new BufferedReader(new InputStreamReader(System.in));
}
@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("over")){
break;
}
} catch (Exception e) {
e.printStackTrace();
}
}
socket.close();
}
}
package com.lesson.chat;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class ChatReceive implements Runnable{
DatagramSocket socket=null;
private int port;
private String msgFrom;
public ChatReceive(int port,String msgFrom) {
this.port = port;
this.msgFrom=msgFrom;
try {
socket = new DatagramSocket(port);
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while (true){
try {
//准备接受包裹
byte[] container = new byte[1024];
DatagramPacket packet = new DatagramPacket(container,0,container.length);
socket.receive(packet);
//断开连接
byte[] data = packet.getData();
String receiveData = new String(data, 0, data.length);
System.out.println(msgFrom+":"+receiveData);
if (receiveData.equals("over")){
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
socket.close();
}
}
package com.lesson.chat;
public class ChatStudent {
public static void main(String[] args) throws Exception {
new Thread(new ChatSend(7777,"localhost",9999)).start();
new Thread(new ChatReceive(8888,"老师"));
}
}
package com.lesson.chat;
public class ChatTeacher {
public static void main(String[] args) throws Exception {
new Thread(new ChatSend(5555,"localhost",8888)).start();
new Thread(new ChatReceive(9999,"学生"));
}
}
7.URL
统一资源定位符
协议://IP地址:端口号/项目名/资源