网络编程
重点:IP地址 端口号
其他:了解
“网络协议”
|—OSI参考模型 七层 从下往上说 ***
应用层 离用户最近的一层
表示层
会话层
传输层
网络层
数据链路层
物理层 离用户最远的
|—TCP/IP协议 — “事实上的标准” 四层/五层
应用层
传输层
网络层
数据链路层
IP地址 :唯一的标识网络中的一台”主机“ 知道IP地址才能找到对方的电脑
唯一的标识Internet上的计算机(通信实体)。
本地回环地址:127.0.0.1
。***
IP
地址分类方式1:
IPV4
:4个字节组成,4个0-255。大概42亿,30亿都在北美,亚洲4亿。2011年初已经用尽。以点分十进制表示,如192.168.0.1
IPV6
:128位(16个字节),写成8个无符号整数,每个整数用四个十六进制位表示, 数之间用冒号:
分开,如:3ffe:3201:1401:1280:c8ff:fe4d:db39:198
IP
地址分类方式2:
- 公网地址(万维网使用)和私有地址(局域网使用)。一般
192.168.
开头的就是私有址址,范围即为192.168.0.0--192.168.255.255
,专门为组织机构内部使用。
端口号:唯一的标识了”主机“上的特定的应用 找到要送到的应用
端口号标识正在计算机上运行的进程(程序),不同的进程有不同的端口号。端口号是一个16
位的整数0~65535
。***
端口分类:
- 公认端口:
0~1023
。被预先定义的服务通信占用(如:HTTP占用端口 80,FTP占用端口21,Telnet占用端口23); - 注册端口:
1024~49151
。分配给用户进程或应用程序(如:Tomcat占用端口8080,MySQL占用端口3306,Oracle占用端口1521等)。 - 动态/私有端口:
49152~65535
。
端口号与IP
地址的组合得出一个网络套接字Socket
。
服务端
服务器程序的工作过程包含以下四个基本的步骤:
- 调用
ServerSocket(int port)
:创建一个服务器端套接字,并绑定到指定端口上。用于监听客户端的请求; - 调用
accept()
:监听连接请求,如果客户端请求连接,则接收连接,返回套接字对象; - 调用该
Socket
类对象的getOutputStream()
和getInputStream()
,获取输出流和输入流,开始网络数据的发送和接收; - 关闭
ServerSocket
和Socket
对象,客户端访问结束,关闭通信套接字。
ServerSocket
对象负责等待客户端请求建立套接字连接,类似邮局某个窗口中的业务员。也就是说,服务器必须事先建立一个等待客户请求建立套接字连接的ServerSocket
对象,这个对象称为监听套接字。
所谓接收客户的套接字请求,就是accept()
方法会返回一个Socket
对象,这个对象称为已连接套接字。
package com.sdut.k7.text5;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
//服务端
public class Server {
public static void main(String[] args) throws IOException {
/**
* 创建服务器
*/
//创建监听套接字 --- 让服务器占用特定的端口,并在端口上进行监听
ServerSocket serverSocket = new ServerSocket(65431);
while (true){
//监听 accept()---一旦有客户端连接服务器,返回已连接套接字,已连接套接字代表客户端
Socket socket = serverSocket.accept();
//获取客户端的地址和端口号
String clientAddress = socket.getInetAddress().getHostAddress();
int port = socket.getPort();
System.out.println("客户端已连接,地址:" + clientAddress + ",端口号:" + port);
//和客户端通信 --- IO流
InputStream in = socket.getInputStream();
//读
byte[] arr = new byte[1024];
int length = 0;
while ((length = in.read(arr,0,1024))!= -1){
String str = new String(arr, 0 , length);
System.out.println(str);
}
//关闭
socket.close();
}
}
}
客户端
客户端Socket
的工作过程包含以下四个基本的步骤:
- 创建
Socket
:根据指定服务端的IP
地址或端口号构造Socket
类对象。若服务器端响应,则建立客户端到服务器的通信线路。若连接失败,会出现异常; - 打开连接到
Socket
的输入/出流: 使用getInputStream()
方法获得输入流,使用getOutputStream()
方法获得输出流,进行数据传输; - 按照一定的协议对
Socket
进行读/写操作:通过输入流读取服务器放入线路的信息 (但不能读取自己放入线路的信息),通过输出流将信息写入线程; - 关闭
Socket
:断开客户端到服务器的连接,释放线路。
package com.sdut.k7.text5;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;
/**
* 基于TCP协议的客户端
* 1.创建套接字,填写服务器的IP和端口号 查看自己电脑IP地址--- cmd打开Dos 输入ipconfig看以太网的IPv4
* 2.获取IO流 读/写
* 3.关闭
*/
public class Client {
public static void main(String[] args) throws IOException {
//创建套接字,填写服务器的IP和端口号
Socket socket = new Socket("127.0.0.1",65031);
//获取IO流
OutputStream out = socket.getOutputStream();
//创建扫描器
Scanner sc = new Scanner(System.in);
while (true){
//获取用户输入
String str = sc.next();
if(str.equals("exit")){
break;
}
//将用户输入发给服务器
out.write(str.getBytes());
}
//关闭socket
socket.close();
}
}
服务器升级–多线程
使用多线程
package com.sdut.k7.text5;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
public class ServerThread extends Thread{
private Socket socket;
public ServerThread(Socket socket){
this.socket = socket;
}
@Override
public void run() {
try {
//获取客户端的地址和端口号
String clientAddress = socket.getInetAddress().getHostAddress();
int port = socket.getPort();
System.out.println("客户端已连接,地址:" + clientAddress + ",端口号:" + port);
//和客户端通信 -- Io流
InputStream in = socket.getInputStream();
byte[] arr = new byte[1024];
int length = 0;
while ((length = in.read(arr,0,1024))!= -1){
String str = new String(arr, 0, length);
System.out.println("地址:"+ clientAddress + "端口号:" + port +"\t\t\t\t" + str);
}
}catch (IOException e) {
e.printStackTrace();
}
//关闭
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com.sdut.k7.text5;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server1 {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(65031);
while (true){
//监听
Socket socket = serverSocket.accept();
//创建服务器线程
ServerThread serverThread = new ServerThread(socket);
//启动线程
serverThread.start();
}
}
}