网络编程入门
软件架构
1、C/S架构:客户端/服务器(淘宝App)
2、B/S架构:浏览器/服务器(网页淘宝)
网络通信协议
网络:互联网/局域网
通信:数据传输
协议:规则规范
协议分类
TCP协议:传输控制协议(Transmission Control Protocol)
IP协议:因特网协议(Internet Protocol)
java中支持的常见协议
TCP协议:传输控制协议,特点是:面向有连接,数据传输之前必须先建立连接,底层是”三次握手“;
优点是:保证数据是完整的。缺点:性能较低。
UDP协议:用户数据报协议,特点是:面向无连接,传输数据时,不需要建立连接,直接将数据发送。
优点是:性能较高。缺点:不能保证数据的完整性和安全性。
网络编程三要素
1、网络通信协议
2、IP地址:每台计算机连接到互联网的IP地址,即唯一标识。由32位二进制组成
3、端口号:一台计算机上不同软件的标识。
IP地址
IPv4:由32位二进制组成。
IPv6:由128位二进制组成
相关命令:
ipconfig:查看本机IP
ping 对方IP:测试本机是否和对方相通。
特殊的IP地址:127.0.01(localhost):本机回环地址。
InetAddress类的基本使用
获取主机IP地址的对象:InetAddress.getLocalHost();
获取其他主机的:InetAddress。getByName(域名/IP地址)
TCP通信程序
客户端:个人设备(手机、电脑等)
服务器端:淘宝、京东等
TCP中的两个重要的类【重点】
Socket类,代表客户端类
构造方法: public Socket(String IP,int port);//服务器的IP地址,服务器的端口号
此构造方法会根据我们传入的参数,自动去连接服务器。如果成功,对象正常创建;如果连接失败,直接抛出异常。
常用方法:
public OutputStream getOutputStream ();//获取连接中的输出流
public InputStream getInputStream ();//获取连接中的输入流
public void shutDownOutput();//关闭连接中的输出流
public void shutDownInput();//关闭连接中的输入流
public void close();//关闭客户端
ServerSocket类,代表服务器端类
构造方法: public ServerSocket(int port);//指定服务器的端口号
常用方法:
public Socket accept();//接受连接到服务器的Socket对象,如果没有客户端,会阻塞。
public void close();//关闭服务器对象
注意:服务器获取到客户端对象后,也可以获取连接中的两个流,但是是相对于服务器而言的。
TCP通信案例
客户端向服务器发送数据【单项通信】
public class SocketDemo {
public static void main(String[] args) throws IOException {
//1、创建socket一个客户端
Socket socket = new Socket("192.168.0.104", 8888);
System.out.println("成功");
//2、获取输出流【字节】
OutputStream outputStream = socket.getOutputStream();
//3、调用write
outputStream.write("你好".getBytes());
//4、释放资源
outputStream.close();
socket.close();
}
}
public class ServerSocketDemo {
public static void main(String[] args) throws IOException {
//1、创建一个服务器端
ServerSocket serverSocket = new ServerSocket(8888);
//2、接受连接到服务器的Socket对象
Socket accept = serverSocket.accept();
//3、获取输入流
InputStream inputStream = accept.getInputStream();
//4、调用read方法
byte[] bytes = new byte[1024];
int len = inputStream.read(bytes);
//5、释放资源
inputStream.close();
accept.close();
serverSocket.close();
}
}
服务器向客户端回写数据【双向通信】
客户端给服务器发信息,服务器给客户端回信息。
客户端:
public class SocketDemo1 {
public static void main(String[] args) throws IOException {
//1、创建socket一个客户端
Socket socket = new Socket("192.168.0.104", 8888);
System.out.println("连接成功");
//2、获取输出流【字节】
OutputStream outputStream = socket.getOutputStream();
//3、调用write
outputStream.write("你好".getBytes());
System.out.println("发送成功");
///**读取服务器回的信息
// * 获取输入流
InputStream inputStream = socket.getInputStream();
// * 调用输入流的read的方法
byte[] bytes = new byte[1024];
int len = inputStream.read(bytes);
System.out.println("服务器回复" + new String(bytes, 0, len));
// */
//4、释放资源
outputStream.close();
socket.close();
System.out.println("服务器关闭");
}
}
服务器端:
public class ServerSocketDemo1 {
public static void main(String[] args) throws IOException {
//1、创建一个服务器端
ServerSocket serverSocket = new ServerSocket(8888);
//2、接受连接到服务器的Socket对象
Socket accept = serverSocket.accept();
//3、获取输入流
InputStream inputStream = accept.getInputStream();
//4、调用read方法
byte[] bytes = new byte[1024];
int len = inputStream.read(bytes);
System.out.println("客户端说" + new String(bytes, 0, len));
///*回信息
//获取输出流
OutputStream outputStream = accept.getOutputStream();
//调用write方法
outputStream.write("信息收到".getBytes());
System.out.println("成功恢复");
// */
//5、释放资源
inputStream.close();
accept.close();
serverSocket.close();
}
}
综合案例
需求:
使用TCP协议实现客户端和服务端互相发送消息。
客户端发送一条消息,服务器读取之后,返回一条消息给客户端,客户端读取服务器返回的消息之后,又发送一条消息…循环执行,直到输入exit。
要求:
1. 消息内容通过键盘输入
2. 要求服务器端和客户端都使用字符流的方式发送和接收数据。
使用BufffferedReader方法readLine()读取一行数据。
使用BufffferedWriter方法write(“字符串的数据”)发送数据。
客户端:
public class demo01 {
public static void main(String[] args) throws IOException {
//创建客户端对象
Socket socket = new Socket("192.168.0.104", 8888);
//字符输出流
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
//字符输入流
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Scanner scanner = new Scanner(System.in);
//无限循环
while (true) {
System.out.println("客户端说:");
String s = scanner.nextLine();
//判断
if (s.equals("exit")) {
break;
}
bufferedWriter.write(s);
//换行
bufferedWriter.newLine();
//刷新
bufferedWriter.flush();
//读取服务器返回的消息
System.out.println("服务器端说:" + bufferedReader.readLine());
}
//释放资源
bufferedReader.close();
bufferedWriter.close();
socket.close();
}
}
服务器端:
public class demo02 {
public static void main(String[] args) throws IOException {
//创建服务器端对象
ServerSocket serverSocket = new ServerSocket(8888);
//接收连接到服务器端的对象
Socket accept = serverSocket.accept();
//字符输入流
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(accept.getInputStream()));
//字符输出流
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(accept.getOutputStream()));
Scanner scanner = new Scanner(System.in);
while (true) {
//接收客户端发送的数据
System.out.println("客户端说:" + bufferedReader.readLine());
System.out.println("服务器说:");
String line = scanner.nextLine();
if (line.equals("exit")) {
break;
}
//写出数据
bufferedWriter.write(line);
//换行
bufferedWriter.newLine();
bufferedWriter.flush();
}
}
}
小结
【重点掌握】
在使用字节输入流时,需要创建字节数组来实现读取数据。
在使用字节输出流时,需要调用getBytes()方法写出数据。