网络编程入门
- C/S结构: 全程为Client/Server结构,是指客户端和服务 器结构。常⻅程序有QQ、迅雷等软件
- 特点:客户端和服务器是分开的,需要下载客户端,对网络要求相对低,开发和维护成本高,相对稳定
- B/S结构:全称为Browser/Server结构,是指浏览器和服务器结构。常⻅浏览器有⾕歌、⽕狐等
-
特点 : 没有客户端 , 只有服务器 , 不需要下载客户端 , 直接通过浏览器访问, 对⽹络要求相对⾼ , 开发和维护成本低 , 服务器压⼒很⼤, 相对不稳定
两种架构各有优势,但是⽆论哪种架构,都离不开⽹络的⽀持。⽹络编程,就是在⼀定的协议下,实现两台计算机的通信的程序。
网络编程,就是在一定的协议下,实现两台计算机的通信的程序。
网络编程三要素
协议
网络通信协议:通信协议是计算机必须遵守的规则,只有遵守这些规则,计算机之间才能进⾏通信。这就好⽐在道路中⾏驶的汽⻋⼀定要遵守交通规则⼀样,协议中对数据的传输格式、传输速率、传输步骤等做了统⼀规定,通信双⽅必须同时遵守,最终完成数据交换。
IP
地址
P
地址:指互联⽹协议地址(
Internet Protocol
Address
)
,俗称
IP
。
IP
地址⽤来给⼀个⽹络中的计算机
设备做唯⼀的编号
。假如我们把
“
个⼈电脑
”
⽐作
“
⼀台电话
”的话,那么“IP
地址
”
就相当于
“
电话号码
”
。
端口号
端⼝号:⽤两个字节表示的整数,它的取值范围是
0~65535
。其中,
0~1023
之间的端⼝号⽤于⼀些知名的⽹络服务和应⽤,普通的应⽤程序需要使⽤1024
以上的端⼝号。如果端⼝号被另外⼀个服务或应⽤所占⽤,会导致当
前程序启动失败。
InetAddress类
InetAddress类的概述
- 一个该类的对象就代表一个IP地址对象。
InetAddress
类的⽅法
- static InetAddress getLocalHost() 获得本地主机IP地址对象
-
static InetAddress getByName(String host) 根据 IP 地址字符串或主机名获得对应的IP 地址对象
-
String getHostName(); 获得主机名
-
String getHostAddress(); 获得 IP 地址字符串
public class Test01 {
//InetAddress类
public static void main(String[] args) throws UnknownHostException {
//获取本地ip地址对象
InetAddress ip1 = InetAddress.getLocalHost();
System.out.println("ip1"+ip1);
//获取百度iddizhiduixinag
InetAddress ip2 = InetAddress.getByName("www.baidu.com");
System.out.println("ip2"+ip2);
//获取本地的主机名
String host = ip1.getHostName();
System.out.println("host"+host);
//获取本地的ip地址
String hostAddress =ip1.getHostAddress();
System.out.println("hostAddress"+hostAddress);
}
}
TCP通信程序
TCP
概述
TCP
协议是⾯向连接的通信协议,即在传输数据前先在发送端和接收器端建⽴逻辑连接,然后再传输数据。它提供了两台计算机之间可靠⽆差错的数据传输。
TCP
协议相关的类
- java.net.Socket : ⼀个该类的对象就代表⼀个客户端程序。
-
Socket(String host, int port) 根据 ip 地址字符串和端⼝号创建客户端Socket 对象 * 注意事项:只要执⾏该⽅法,就会⽴即连接指定的服务器程序,如果连接不成功,则会抛出异常。 如果连接成功,则表示三次握⼿通过。
-
OutputStream getOutputStream(); 获得字节输出流对象
-
InputStream getInputStream(); 获得字节输⼊流对象
-
void close(); 关闭 Socket, 会⾃动关闭相关的流
-
-
java.net.ServerSocket : ⼀个该类的对象就代表⼀个服务器端程序。
-
ServerSocket(int port); 根据指定的端⼝号开启服务器。
-
Socket accept(); 等待客户端连接并获得与客户端关联的Socket 对象 如果没有客户端连接 , 该⽅法会⼀直阻塞
-
void close(); 关闭 ServerSocket, ⼀般不关闭
-
public class Test02 {
//Tcp通信程序
public static void main(String[] args) throws IOException {
while (true) {
//创建Socket对象,指定服务器ip和端口号
Socket socket = new Socket("192.168.0.168", 666);
//通过socket对象获得输出流
OutputStream os = socket.getOutputStream();
//写出数据
Scanner sc = new Scanner(System.in);
System.out.println("请输入向服务器发送的数据:");
String str = sc.nextLine();
os.write(str.getBytes());
InputStream is = socket.getInputStream();
//读取
byte[] bys = new byte[1024];
int len = is.read(bys);
System.out.println(new String(bys,0,len));
//关闭流,释放资源
// socket.close();
}
}
}
服务器:
public class Test03{
public static void main(String[] args) throws IOException {
//创建ServerSoket对象,并指定端口号
ServerSocket ss = new ServerSocket(666);
//调用accept()方法等待客户端连接,连接成功返回Socket对象
Socket socket = ss.accept();
while (true) {
//通过Socket对象获得输入流
InputStream is = socket.getInputStream();
//定义一个byte数组,用来存储读取到的字节数组
byte[] bys = new byte[1024];
int len = is.read(bys);
//打印
System.out.print("客户端返回回来的话:");
System.out.println(new String(bys,0,len));
//通过socket对象获得输出流
OutputStream os = socket.getOutputStream();
//写入数据
Scanner sc = new Scanner(System.in);
System.out.println("请输入向客户端发送的数据:");
String str = sc.nextLine();
os.write(str.getBytes());
//关闭资源
// socket.close();
// ss.close();//服务器一般不关闭
}
}
}
Tcp客户端代码2
public class Client {
public static void main(String[] args)
throws Exception{
// 创建Socket对象,指定服务器ip和端⼝号
Socket socket = new Socket("127.0.0.1",6666);
while (true) {
// 通过socket对象获得输出流
OutputStream os =socket.getOutputStream();
// 写出数据
Scanner sc = new Scanner(System.in);
System.out.println("请输⼊向服务器发送的数据:");
String str = sc.nextLine();
os.write(str.getBytes());
// 通过Socket对象获得输⼊流
InputStream is =socket.getInputStream();
// 定义⼀个byte数组,⽤来存储读取到的字节数据
byte[] bys = new byte[1024];
int len = is.read(bys);
// 打印数据
System.out.println(new String(bys,0,len));
}
// 关闭流,释放资源
//socket.close();
}
}
服务器:
public class Server {
public static void main(String[] args)
throws Exception{
// 创建ServerSocket对象,并指定端⼝号
ServerSocket ss = new ServerSocket(6666);
// 调⽤accept()⽅法等待客户端连接,连接成功返回Socket对象
Socket socket = ss.accept();
while (true) {
// 通过Socket对象获得输⼊流
InputStream is =socket.getInputStream();
// 定义⼀个byte数组,⽤来存储读取到的字节数据
byte[] bys = new byte[1024];
int len = is.read(bys);
// 打印数据
System.out.println(newString(bys,0,len));
// 通过socket对象获得输出流
OutputStream os =socket.getOutputStream();
// 写出数据
Scanner sc = new Scanner(System.in);
System.out.println("请输⼊向客户端发送的数据:");
String str = sc.nextLine();
os.write(str.getBytes());
}
// 关闭资源
//socket.close();
//ss.close();// 服务器⼀般不关闭
}
}
综合案例
1.
【客户端】输⼊流,从硬盘读取⽂件数据到程序中。
2.
【客户端】输出流,写出⽂件数据到服务端。
3.
【服务端】输⼊流,读取⽂件数据到服务端程序。
4.
【服务端】输出流,写出⽂件数据到服务器硬盘中。
5.
【服务端】获取输出流,回写数据。
6.
【客户端】获取输⼊流,解析回写数据。
拷贝文件
public class Client {
public static void main(String[] args)
throws Exception{
// 客户端:
// 1.创建Socket对象,指定服务器的ip地址和端⼝号
Socket socket = new Socket("127.0.0.1",7777);
// 2.创建字节输⼊流对象,关联数据源⽂件路径
FileInputStream fis = new FileInputStream("day14\\aaa\\4.jpg");
// 3.通过Socket对象,获取输出流对象
OutputStream os = socket.getOutputStream();
// 4.定义⼀个字节数组,⽤来存储读取到的字节数据
byte[] bys = new byte[8192];
// 4.定义⼀个int类型的变量,⽤来存储读取到的字节个数
int len;
// 5.循环读取数据
while ((len = fis.read(bys)) != -1) {
// 6.在循环中,写出数据
os.write(bys,0,len);
}
// 7.关闭流,释放资源
fis.close();
socket.close();
}
}
class Server {
public static void main(String[] args)
throws Exception{
// 服务器:
// 1.创建ServerSocket对象,指定服务器端⼝号
ServerSocket ss = new ServerSocket(7777);
// 2.调⽤accept()⽅法,接收客户端的请求,建⽴连接,返回Socket对象
Socket socket = ss.accept();
// 3.通过Socekt对象获取字节输⼊流
InputStream is = socket.getInputStream();
// 4.创建字节输出流对象,关联⽬的地⽂件路径
FileOutputStream fos = new FileOutputStream("day14\\bbb\\44.jpg");
// 5.定义⼀个字节数组,⽤来存储读取到的字节数据
byte[] bys = new byte[8192];
// 5.定义⼀个int类型的变量,⽤来存储读取到的字节个数
int len;
// 6.循环读取数据
while ((len = is.read(bys)) != -1) {
// 7.在循环中,写出数据
fos.write(bys,0,len);
}
// 8.关闭流,释放资源
fos.close();
socket.close();
}
}