网络编程将数据通过规定好的协议进行包装,接收端按照规定好的协议进行解析,从而获取数据,达到通信的目的。
2.如何实现网络编程?每台主机都有一个IP地址,我们只要知道IP地址便可以通过TCP或UDP协议去访问它
最常见的本机地址就是127.0.0.1,还有另外一个名字localhost
我们通过ip地址就能确定唯一一台主机,但是通过端口号和协议,我们就可以确定主机的某一个进程。
端口号有TCP和UDP两种,这两种协议的端口号不冲突(TCP有3000端口号,UDP也有3000端口号)
我们可以将主机的ip看做是楼号,TCP和UDP可以看做是单元号,将端口号看做是楼房的门牌号。
每一个单元都有1,2,3,4,5…门牌号,但是同一栋楼不同单元的同一个门牌号住着不同的人。(也就是同一个计算机不同协议下的同一个端口号运行着不同的服务)
计算机给我们提供的端口号是0~65535 * 2(TCP/UDP)
其中0~1023属于公认端口,是留给计算机系统的程序使用的
比如:
HTTP: 80
HTTPS: 443
FTP: 21
Telent: 23
1024~49151属于临时端口,留给应用程序或用户使用的
比如:
MySQL:3306
Tomcat:8080
剩下的49152~65535属于动态/私有(服务器)端口
4通信协议netstat -ano 可以查看所有的端口
我们最常见的也是最重要的两个协议TCP/UDP
- TCP:用户传输协议
- 三次握手、四次挥手
- 有明确的客户端和服务端
- 安全性高,传输效率高
- UDP:用户数据报协议
- 不稳定、不需要连接
- 既可以是客户端也可以是服务端
- 不安全,丢包后客户端不知道
服务端
ServerSocket serverSocket = null;
Socket accept = null;
InputStream inputStream = null;
ByteArrayOutputStream bs = null;
try {
//1.开放一个端口号用于通信
serverSocket = new ServerSocket(6666);
//持续监听客户端消息
while (true) {
//2.监听,等待客户端连接
accept= serverSocket.accept();
//3.读取客户端的消息
inputStream = accept.getInputStream();
//4.通过管道流,防止传输中文异常
bs = new ByteArrayOutputStream();
byte[] bytes = new byte[1024];
int len;
//读取管道信息
while ((len = inputStream.read(bytes)) != -1) {
bs.write(bytes, 0, len);
}
System.out.println(bs);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
//关闭资源
if (bs!=null){
try {
bs.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (inputStream!=null){
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (accept!=null){
try {
accept.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (serverSocket!=null){
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端
InetAddress byAddress = null;
Socket socket = null;
OutputStream outputStream = null;
try {
//1.要知道服务器的地址
byAddress = InetAddress.getByName("127.0.0.1");
//2.端口号
int port = 6666;
//3.创建一个Socket连接,同过地址和端口号与服务器通信
socket = new Socket(byAddress, port);
//4.发送消息,使用输出流
outputStream = socket.getOutputStream();
outputStream.write("Helloworld".getBytes());
} catch (IOException e) {
e.printStackTrace();
}finally {
if(outputStream!=null){
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket!=null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
接收到了客户端的消息
服务端
//1.创建服务,开放端口
ServerSocket serverSocket = new ServerSocket(6666);
//2.监听客户端连接
//阻塞式监听,会一直等待客户端连接
Socket accept = serverSocket.accept();
//3.获取输入流
InputStream inputStream = accept.getInputStream();
//4.文件输出
FileOutputStream fileOutputStream = new FileOutputStream("t1.txt");
byte[] bytes = new byte[200];
int len;
//读取输入流中的数据
while ((len=inputStream.read(bytes))!=-1){
//输出缓存中的数据
fileOutputStream.write(bytes,0,len);
}
//通知客户端,信息接收完毕
OutputStream outputStream = accept.getOutputStream();
outputStream.write("信息接收完毕".getBytes());
//关闭连接
fileOutputStream.close();
inputStream.close();
accept.close();
serverSocket.close();
客户端
//1.创建服务连接
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 6666);
//2.创建一个输出流
OutputStream outputStream = socket.getOutputStream();
//3.读取文件
FileInputStream stream = new FileInputStream("123.txt");
//4.创建缓存写文件
byte[] bytes = new byte[200];
int len;
while ((len=stream.read(bytes ))!=-1){
outputStream.write(bytes,0,len);
}
//通知服务器已经结束了,传输完毕
socket.shutdownOutput();
//接收客户端传来的消息,确认消息传输完毕
InputStream inputStream = socket.getInputStream();
//创建管道流,获取服务端发送的消息
ByteArrayOutputStream bs = new ByteArrayOutputStream();
byte[] byt2 =new byte[200];
int len2;
while ((len2=inputStream.read(byt2))!=-1){
bs.write(byt2,0,len2);
}
System.out.println(bs);
//5.关闭连接
stream.close();
outputStream.close();
socket.close();
7.总结
我们在使用网络通信的时候,需要知道对方的ip和端口号,并且当前对方的端口进程也在接受消息,才能传输信息,否则会传输失败。
传输字节使用字节流,传输文件使用文件流。
传输完毕后需要关闭连接。



