一、网络编程入门
1.网络编程概述
网络编程:
- 在网络通信协议下,实现网络互连的不同计算机上运行的程序间可以进行数据交换
2.网络编程三要素
ip地址:
- 要想让网络中的计算机能够互相通信,必须为每台计算机指定一个标识号。通过这个标识号来指定要接收数据的计算机和识别发送的计算机,而IP地址就是这个标识号。也就是设备的标识
- 常用命令:
- ipconfig:查看本机ip地址
- ping IP地址:检查网络是否连通
- 特殊IP地址:
- 127.0.0.1:是回送地址,可以代表本机地址,一般用来测试使用。
端口:
- 网络的通信,本质上是两个应用程序的通信。每台计算机都有很多的应用程序,那么在网络通信时,如何区分这些应用程序呢?如果说IP地址可以唯一标识网络中的设备,那么端口号就可以唯一标识设备中的应用程序了。也就是应用程序的标识
协议:
- 通过计算机网络可以使多态计算机实现连接,位于同一个网络中的计算机在进行连接和通信时需要遵守一定的规则,这就好比在道路中行驶的汽车一定要遵守交通规则一样。在计算机网络中,这些连接和通信的规则被称为网络通信协议,它对数据的传输格式、传输速率、传输步骤等做了统一规定,通信双方必须同时遵守才能完成数据交换。常见的协议有UDP协议和TCP协议。
3.InetAddress的使用
为了方便我们对IP地址的获取和操作,java提供了一个类InetAddress供我们使用
InetAddress:此类表示Internet协议(IP)地址
方法名 | 说明 |
---|---|
static InetAddress getByName(String host) | 确定主机名称的IP地址。主机名称可以是机器名称,也可以是IP地址 |
String getHostName() | 获取此IP地址的主机号 |
String getHostAddress() | 返回文本显示中的IP地址字符串 |
public class InetAddressDemo {
public static void main(String[] args) throws UnknownHostException {
InetAddress address = InetAddress.getByName("www.baidu.com");
InetAddress localHost = InetAddress.getLocalHost();
String name1 = address.getHostName();
String name2 = localHost.getHostName();
String ip1 = address.getHostAddress();
String ip2 = localHost.getHostAddress();
System.out.println("主机名" + name1);
System.out.println("IP地址:" + ip1);
System.out.println("主机名" + name2);
System.out.println("IP地址:" + ip2);
}
}
二、UDP通信程序
1.UDP通信原理
UDP协议是一种不可靠的网络协议,它在通信的两端各建立一个Socket对象,但是这两个Socket只是发送,接收数据的对象。
2.UDP发送数据
发送数据的步骤
- 创建发送端的Socket对象(DatagramSocket)
- 创建数据,并把数据打包
- 调用DatagramSocket对象的方法发送数据
- 关闭发送端
public class SendDemo {
public static void main(String[] args) throws IOException {
//创建发送端的Socket对象(DatagramSocket)
//DatagramSocket()构造数据报套接字并将其绑定到本地主机上的任何端口
DatagramSocket ds = new DatagramSocket();
//创建数据,并把数据打包
//DatagramPocket(byte[] buf,int length,InetAddress address,int port)
//构造一个数据包,发送长度为 length的数据包到指定主机上的指导端口号
byte[] bys = "hello,udp,i am coming".getBytes();
// int length = bys.length;
// InetAddress address = InetAddress.getByName("192.168.147.1");
// int port = 10086;
DatagramPacket dp = new DatagramPacket(bys,bys.length,InetAddress.getByName("192.168.147.1"),10086);
//调用DatagramSocket对象的方法发送数据
ds.send(dp);
//关闭发送端
ds.close();
}
}
3.UDP接收数据
接收数据的步骤
- 创建接收端的Socket对象(DatagramSocket)
- 创建一个数据包,用于接收数据
- 调用DatagramSocket对象的方法接收数据
- 解析数据包,并把数据在控制台显示
- 关闭接收端
public class ReceiveDemo {
public static void main(String[] args) throws IOException {
//创建接收端的Socket对象(DatagramSocket)
DatagramSocket ds = new DatagramSocket(10086);
//创建一个数据包,用于接收数据
byte[] bys = new byte[1024];
DatagramPacket dp = new DatagramPacket(bys,bys.length);
//调用DatagramSocket对象的方法接收数据
ds.receive(dp);
//解析数据包,并把数据在控制台中显示
//byte[] getData() 返回数据缓冲区
byte[] datas = dp.getData();
int len = dp.getLength();
String dataString = new String(datas,0,len);
System.out.println("数据是:" + dataString);
//关闭接收端
ds.close();
}
}
4.UDP通信程序练习
按照下面的要求实现程序
- UDP发送数据:数据来自于键盘录入,指导输入的数据是886,发送数据结束
- UDP接收数据:因为接收端不知道发送端什么时候停止发送,故用死循环接收
三、TCP通信程序
1.TCP发送数据
发送数据的步骤:
- 创建客户端的Socket对象(Socket)
- 获取输出流,写数据
- 释放资源
public class ClientDemo {
public static void main(String[] args) throws IOException {
//创建客户端的Socket对象
//Socket s = new Socket(InetAddress.getByName("192.168.147.1"),10000);
Socket s = new Socket("192.168.147.1",10000);
//获取输出流,写数据
//OutputStream getOutputStream() 返回此套接字的输出流
OutputStream os = s.getOutputStream();
os.write("hello,tcp,i am coming".getBytes());
s.close();
}
}
2.TCP接收数据
接收数据的步骤:
- 创建服务器端的Socket对象(ServerSocket)
- 获取输入流,读数据,并把数据显示在控制台
- 释放资源
public class ServerDemo {
public static void main(String[] args) throws IOException {
//创建服务器端的Socket对象(ServerSocket)
//ServerSocket(int port) 创建绑定到指定端口的服务器套接字
ServerSocket ss = new ServerSocket(10000);
//Socket accept()侦听要连接到此套接字并接受它
Socket s = ss.accept();
//获取输入流,读数据,并把数据显示在控制台
InputStream is = s.getInputStream();
byte[] bys = new byte[1024];
int len = is.read(bys);
String data = new String(bys,0,len);
System.out.println("数据是:"+data);
s.close();
ss.close();
}
}
3.案例
1)练习1
客户端:发送数据,接收服务器反馈
服务器:接收数据,给出反馈
public class ClientDemo {
public static void main(String[] args) throws IOException {
//创建客户端的Socket对象
//Socket s = new Socket(InetAddress.getByName("192.168.147.1"),10000);
Socket s = new Socket("192.168.147.1",10000);
//获取输出流,写数据
//OutputStream getOutputStream() 返回此套接字的输出流
OutputStream os = s.getOutputStream();
os.write("hello,tcp,i am coming".getBytes());
//接收服务器反馈
InputStream is = s.getInputStream();
byte[] bys = new byte[1024];
int len = is.read(bys);
String data = new String(bys,0,len);
System.out.println("客户端:"+data);
s.close();
}
}
public class ServerDemo {
public static void main(String[] args) throws IOException {
//创建服务器端的Socket对象(ServerSocket)
//ServerSocket(int port) 创建绑定到指定端口的服务器套接字
ServerSocket ss = new ServerSocket(10000);
//Socket accept()侦听要连接到此套接字并接受它
Socket s = ss.accept();
//获取输入流,读数据,并把数据显示在控制台
InputStream is = s.getInputStream();
byte[] bys = new byte[1024];
int len = is.read(bys);
String data = new String(bys,0,len);
System.out.println("服务器:"+data);
OutputStream os = s.getOutputStream();
os.write("数据已经收到".getBytes());
s.close();
ss.close();
}
}
2)练习2
客户端:数据来自于键盘录入,直到输入的数据是886,发送数据结束
服务器:接收到的数据在控制台输出
public class ClientDemo {
public static void main(String[] args) throws IOException {
Socket s = new Socket("192.168.147.1",10000);
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String line;
while((line = br.readLine()) != null){
if("886".equals(line)){
break;
}
// OutputStream os = s.getOutputStream();
// os.write(line.getBytes());
bw.write(line);
bw.newLine();
bw.flush();
}
s.close();
}
}
public class ServerDemo {
public static void main(String[] args) throws IOException {
//创建服务器端的Socket对象(ServerSocket)
//ServerSocket(int port) 创建绑定到指定端口的服务器套接字
ServerSocket ss = new ServerSocket(10000);
//Socket accept()侦听要连接到此套接字并接受它
Socket s = ss.accept();
// InputStream is = s.getInputStream();
// InputStreamReader isr = new InputStreamReader(is);
// BufferedReader br = new BufferedReader(isr);
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line;
while((line=br.readLine())!=null){
System.out.println(line);
}
ss.close();
}
}
3)练习3
客户端:数据来自于键盘录入,直到输入的数据是886,发送数据结束
服务器:接收到的数据写入文本文件
public class ClientDemo {
public static void main(String[] args) throws IOException {
Socket s = new Socket("192.168.147.1",10000);
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String line;
while((line = br.readLine()) != null){
if("886".equals(line)){
break;
}
// OutputStream os = s.getOutputStream();
// os.write(line.getBytes());
bw.write(line);
bw.newLine();
bw.flush();
}
s.close();
}
}
public class ServerDemo {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(10000);
Socket s = ss.accept();
//接收数据
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
//把数据写入文本文件
BufferedWriter bw = new BufferedWriter(new FileWriter("E:\\s.txt"));
String line;
while ((line=br.readLine())!=null){
bw.write(line);
bw.newLine();
bw.flush();
}
bw.close();
ss.close();
}
}
4)练习4
客户端:数据来自于文本文件
服务器:接收到的数据写入文本文件
public class ClientDemo {
public static void main(String[] args) throws IOException {
Socket s = new Socket("192.168.147.1",10000);
//封装文本文件的数据
BufferedReader br = new BufferedReader(new FileReader("E:\\s.txt"));
//封装输出流写数据
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String line;
while((line = br.readLine()) != null){
bw.write(line);
bw.newLine();
bw.flush();
}
br.close();
s.close();
}
}
public class ServerDemo {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(10000);
Socket s = ss.accept();
//接收数据
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
//把数据写入文本文件
BufferedWriter bw = new BufferedWriter(new FileWriter("F:\\s.txt"));
String line;
while ((line=br.readLine())!=null){
bw.write(line);
bw.newLine();
bw.flush();
}
bw.close();
ss.close();
}
}
5)练习5
客户端:数据来自于文本文件,接收服务器反馈
服务器:接收到的数据写入文本文件,给出反馈
结束标记:shutdownOutput()
public class ClientDemo {
public static void main(String[] args) throws IOException {
Socket s = new Socket("192.168.147.1",10000);
//封装文本文件的数据
BufferedReader br = new BufferedReader(new FileReader("E:\\s.txt"));
//封装输出流写数据
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String line;
while((line = br.readLine()) != null){
bw.write(line);
bw.newLine();
bw.flush();
}
// //自定义结束标记
// bw.write("886");
// bw.newLine();
// bw.flush();
s.shutdownOutput();
//接收反馈
BufferedReader brClient = new BufferedReader(new InputStreamReader(s.getInputStream()));
String data = brClient.readLine();
System.out.println("服务器的反馈:"+data);
br.close();
s.close();
}
}
public class ServerDemo {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(10000);
Socket s = ss.accept();
//接收数据
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
//把数据写入文本文件
BufferedWriter bw = new BufferedWriter(new FileWriter("F:\\s.txt"));
String line;
while ((line=br.readLine())!=null){
// if("886".equals(line)){
// break;
// }
bw.write(line);
bw.newLine();
bw.flush();
}
//给出反馈
BufferedWriter bwServer = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
bwServer.write("文件上传成功");
bwServer.newLine();
bwServer.flush();
bw.close();
ss.close();
}
}