java.net 包中提供了两种常见的网络协议的支持:
在发送数据之前,首先应该知道服务端的IP地址信息和端口信息,这样才能在网络中找到接收端和确认接收端的具体接受程序。通过InetAddress类的getByName(“127.0.0.1”)方法来获取接收方IP地址信息
// 1.要知道服务器的地址
InetAddress serverIp = InetAddress.getByName("127.0.0.1");
// 2.端口号
int port = 9999;
// 3.创建一个socket连接
socket = new Socket(serverIp, port);
通过Socket套接字获取输出流,然后通过输出流的write方法输入字节数组
// 4.发送消息的IO流
outputStream = socket.getOutputStream();
outputStream.write("你好,我是客户端!".getBytes());
客户端完整代码
Socket socket = null;
OutputStream outputStream = null;
try {
// 1.要知道服务器的地址
InetAddress serverIp = InetAddress.getByName("127.0.0.1");
// 2.端口号
int port = 9999;
// 3.创建一个socket连接
socket = new Socket(serverIp, port);
// 4.发送消息的IO流
outputStream = socket.getOutputStream();
outputStream.write("你好,我是客户端!".getBytes());
} catch (Exception 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();
}
}
}
在完成之后要记得把打开的几个输出流资源进行关闭
服务端需要一直开启等待客户端发送数据,接收到数据之后通过一个管道流将数据读取出来。同时也可以返回数据给客户端,返回数据时,客户端和服务端的角色进行对调一下,服务端发送数据,客户端变成接收数据的一方。
ServerSocket serverSocket = null;
Socket accept = null;
InputStream inputStream = null;
ByteArrayOutputStream baos = null;
try {
// 1.创造一个地址
serverSocket = new ServerSocket(9999);
// 2.等待客户端连接过来
accept = serverSocket.accept();
// 3.读取客户端发送的消息
inputStream = accept.getInputStream();
// 管道流
baos = new ByteArrayOutputStream();
byte[] bytes = new byte[1024];
int len;
while((len = inputStream.read(bytes)) != -1){
baos.write(bytes,0,len);
}
System.out.println(baos.toString());
} catch (IOException e) {
e.printStackTrace();
} finally {
if(baos != null){
try {
baos.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();
}
}
}
因为TCP连接方式是一种比较可靠的连接方式,所以我们也可以通过TCP的方式进行文件的发送与接收,使用一个存放在项目根目录下的logo.jpg文件,从客户端发送到服务端,服务端将该文件保存到项目根目录下,命名为receive.jpg文件,并返回一条数据信息。
客户端
InetAddress ip = InetAddress.getByName("127.0.0.1");
int port = 6666;
Socket socket = new Socket(ip,port);
OutputStream os = socket.getOutputStream();
FileInputStream fis = new FileInputStream(new File("logo.jpg"));
byte[] buffer = new byte[1024];
int len;
while((len = fis.read(buffer)) != -1){
os.write(buffer,0,len);
}
// 通知服务器,我已经结束了
// 如果不通知服务器客户端已经结束,服务器程序会一直运行,不会停止(一直监听)
socket.shutdownOutput();
InputStream is = socket.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] bytes = new byte[1024];
int length;
while((length = is.read(bytes)) != -1){
baos.write(bytes,0,length);
}
System.out.println(baos.toString());
baos.close();
is.close();
fis.close();
os.close();
socket.close();
当客户端文件发送完毕之后要使用socket.shutdownOutput();方法通知服务端客户端的文件发送已经完毕,让服务端关闭连接,否则服务端程序会一直开启不自动关闭。
该方法官方文档的解释是:禁用此套接字的输出流*
服务端
ServerSocket serverSocket = new ServerSocket(6666);
Socket accept = serverSocket.accept();
InputStream is = accept.getInputStream();
FileOutputStream fos = new FileOutputStream(new File("receive.jpg"));
byte[] buffer = new byte[1024];
int len;
while((len = is.read(buffer)) != -1){
fos.write(buffer,0,len);
}
OutputStream os = accept.getOutputStream();
os.write("接收完毕!".getBytes());
os.close();
fos.close();
is.close();
accept.close();
serverSocket.close();