java网络编程基础
回顾计算机网络的相关知识
通信需要IP地址和端口号,InetAddress类主要用来表示IP地址。
可通过域名或者直接写入Ip地址的方式获得对应的ip。
如果想获取本地服务器的相关数据,ip设置为127.0.0.1,对应着localhost。
@Test
public void test() {
try {
InetAddress inetAddress = InetAddress.getByName("182.61.200.6");
System.out.println(inetAddress);
InetAddress byName = InetAddress.getByName("www.baidu.com");
System.out.println(byName);
InetAddress byName1 = InetAddress.getByName("127.0.0.1");
System.out.println(byName1);
InetAddress localHost = InetAddress.getLocalHost();
System.out.println(localHost);
String hostName = byName.getHostName();
System.out.println(hostName); //得到ip对象对应的域名
String hostAddress = byName.getHostAddress();
System.out.println(hostAddress);//得到ip对象对应的ip地址
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
基于Socket的TCP网络编程
客户端Socket的工作过程包含以下四个基本的步骤:
- 创建 Socket: 根据指定服务端的 IP 地址或端口号构造Socket 类对象。若服务器端响应,则建立客户端到服务器的通信线路。若连接失败,会出现异常。
- 打开连接到 Socket 的输入/出流: 使用 getInputStream()方法获得输入流,使用getOutputStream()方法获得输出流,进行数据传输
- 按照一定的协议对 Socket 进行读/写操作: 通过输入流读取服务器放入线路的信息(但不能读取自己放入线路的信息),通过输出流将信息写入线程。
- 关闭 Socket: 断开客户端到服务器的连接,释放线路
服务器程序的工作过程包含以下四个基本的步骤:
- 调用 ServerSocket(int port) : 创建一个服务器端套接字,并绑定到指定端口上。用于监听客户端的请求。
- 调用 accept(): 监听连接请求,如果客户端请求连接,则接受连接,返回通信套接字对象。
- 调用 该Socket类对象的 getOutputStream() 和 getInputStream (): 获取输出流和输入流,开始网络数据的发送和接收。
- 关闭ServerSocket和Socket对象: 客户端访问结束,关闭通信套接字。
package com.senior.internetsocket;
import org.junit.Test;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @author eden
* @Description 客户端发送信息给服务端,服务端将其显示在控制台上。
* @create projectTest-com.senior.internetsocket:2021-05-14-10:52
* @since
*/
public class TCPTest {
//客户端
@Test
public void client() {
Socket socket = null;
OutputStream outputStream = null;
try {
//客户端创建一个socket对象
InetAddress inetAddress = InetAddress.getLocalHost();
// InetAddress inetAddress = InetAddress.getByName("127.0.0.1");
socket = new Socket(inetAddress,8899);
//创建输出流输出信息
outputStream = socket.getOutputStream();
outputStream.write("首次建立通信".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();
}
}
}
}
//服务端
@Test
public void server(){
ServerSocket serverSocket = null;
Socket accept = null;
InputStream inputStream = null;
ByteArrayOutputStream arrayOutputStream = null;
try {
serverSocket = new ServerSocket(8899);
accept = serverSocket.accept();
inputStream = accept.getInputStream();
//由于汉字占3个字节,当byte数组容量设置较小时,可能会出现乱码,因此不建议这样写
// byte[] bytes = new byte[2];
// int len;
// while((len = inputStream.read(bytes))!=-1)
// {
// String s = new String(bytes,0,len);
// System.out.print(s);
// }
arrayOutputStream = new ByteArrayOutputStream();
byte[] bytes = new byte[5];
int len;
while((len = inputStream.read(bytes))!=-1)
{
//ByteArrayOutputStream会把所有的字节依次放入到一个string中,
//这样就不会因为拆包而导致乱码
arrayOutputStream.write(bytes,0,len);
}
System.out.print(arrayOutputStream.toString());
System.out.println();
System.out.println("收到来自"+accept.getInetAddress().getHostName()+"的信息");//可查看客户端是谁发过来的
System.out.println("其对应的IP地址:"+accept.getInetAddress().getHostAddress());
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(arrayOutputStream!=null){arrayOutputStream.close();}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(inputStream!=null){inputStream.close();}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(accept!=null){accept.close();}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(serverSocket!=null){serverSocket.close();}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
package com.senior.internetsocket;
import org.junit.Test;
import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @author eden
* @Description 客户端发送图片给服务端,服务端接收将其保存下来,并给客户端一个反馈。
* @create projectTest-com.senior.internetsocket:2021-05-14-10:52
* @since
*/
public class TCPTest2 {
//客户端
@Test
public void client() {
Socket socket = null;
OutputStream os = null;
FileInputStream fileInputStream = null;
InputStream inputStream =null;
ByteArrayOutputStream byteArrayOutputStream =null;
try {
//1.客户端创建socket套接字
socket = new Socket(InetAddress.getLocalHost(), 9090);
//2.创建输出流
os = socket.getOutputStream();
//3.文件输入流,先把文件读入再让os写出去
fileInputStream = new FileInputStream(new File("pic.jpeg"));
//4.fileInputStream读文件然后os往出写文件
byte[] bytes = new byte[512];
int len;
while((len = fileInputStream.read(bytes))!=-1)
{
os.write(bytes,0,len);
}
//当客户端传完数据之后shutdown一下,这样服务端就知道客户端传完了
//服务端就不会一直等待
socket.shutdownOutput();
//5.等待服务端发来反馈,将其显示到控制台
inputStream = socket.getInputStream();
byteArrayOutputStream = new ByteArrayOutputStream();
//6.inputStream读取来自服务端的信息
//并通过baos将其输出到控制台
byte[] bytes1 = new byte[3];
int len1;
while((len1=inputStream.read(bytes1))!=-1)
{
byteArrayOutputStream.write(bytes1,0,len1);
}
System.out.println(byteArrayOutputStream.toString());
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(inputStream!=null){inputStream.close();}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(byteArrayOutputStream!=null){byteArrayOutputStream.close();}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(fileInputStream!=null){fileInputStream.close();}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(os!=null){os.close();}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(socket!=null){socket.close();}
} catch (IOException e) {
e.printStackTrace();
}
}
}
//服务端
@Test
public void server(){
ServerSocket serverSocket = null;
Socket socket = null;
InputStream inputStream = null;
FileOutputStream fileOutputStream = null;
OutputStream outputStream =null;
try {
//创建serverSocket
serverSocket = new ServerSocket(9090);
socket = serverSocket.accept();
//得到输入流,此时图片信息在输入流中
inputStream = socket.getInputStream();
//再通过FileOutputStream把图片文件保存
fileOutputStream = new FileOutputStream(new File("TCP_pic.jpeg"));
byte[] bytes = new byte[512];
int len;
//inputStream的read方法是一个阻塞式的方法
while((len=inputStream.read(bytes))!=-1)
{
fileOutputStream.write(bytes,0,len);
}
//服务器端给客户端一个反馈
outputStream = socket.getOutputStream();
outputStream.write("资源已收到,接收成功".getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(outputStream!=null){outputStream.close();}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(fileOutputStream!=null){fileOutputStream.close();}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(inputStream!=null){inputStream.close();}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(socket!=null){socket.close();}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(serverSocket!=null){serverSocket.close();}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
该博客图片来源于尚硅谷宋老师教学课件