該文只涉及Socket和IO(不含NIO)
復(fù)習(xí)經(jīng)典網(wǎng)絡(luò)結(jié)構(gòu)
Socket
Berkeley sockets is a Unix application programming interface (API) for Internet sockets and Unix domain sockets, used for inter-process communication (IPC). It is commonly implemented as a libraryof linkable modules. It originated with the 4.2BSD Unix released in 1983.
A socket is an abstract representation (handle) for the local endpoint of a network communication path. The Berkeley sockets API represents it as a file descriptor (file handle) in the Unix philosophy that provides a common interface for input and output to streams of data.
<<from wikipedia>>
為了易懂,程序直接拷貝過(guò)來(lái)跃须,沒(méi)有使用接口繼承等方式站叼。
服務(wù)端程序1
package com.loyotech.bigscreenbackend.socket;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @program big-screen-backend
* @description 網(wǎng)絡(luò)互聯(lián), 發(fā)送消息
* @author Rudolph Browne
* @create 19-1-12
*/
public class ServerSocket1 {
public static void main(String[] args) throws IOException {
// 暴露服務(wù), 端點(diǎn)地址: 本機(jī)IP和8888
try(ServerSocket server = new ServerSocket(8888);
Socket socket = server.accept()) {
System.out.println("與客戶端連接成功...");
acceptMessage(socket);
sendMessage(socket, "Connection Success", "服務(wù)端消息");
}
}
/**
* 發(fā)送1M的消息
* @param socket
* @param message
* @throws IOException
*/
private static void sendMessage(Socket socket, String message, String messageType) throws IOException {
OutputStream messageOut = socket.getOutputStream();
messageOut.write((messageType + " : " + message).getBytes());
socket.shutdownOutput();
}
/**
* 讀取1M數(shù)據(jù)量的消息
* @param socket
* @throws IOException
*/
private static void acceptMessage(Socket socket) throws IOException {
InputStream messageIn = socket.getInputStream();
byte[] buf = new byte[1024];
int len = messageIn.read(buf);
System.out.println(new String(buf, 0, len));
socket.shutdownInput();
}
}
客戶端程序1
package com.loyotech.bigscreenbackend.socket;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
/*
* @program big-screen-backend
* @description
* @author Rudolph Browne
* @create 19-1-12
*/
public class ClientSocket1 {
public static void main(String[] args) throws IOException {
try(Socket socket = new Socket("192.168.0.104", 8888)) {
sendMessage(socket, "Test Connection", "客戶端消息");
acceptMessage(socket);
}
}
/**
* 發(fā)送1M的消息
* @param socket
* @param message
* @throws IOException
*/
private static void sendMessage(Socket socket, String message, String messageType) throws IOException {
OutputStream messageOut = socket.getOutputStream();
messageOut.write((messageType + " : " + message).getBytes());
socket.shutdownOutput();
}
/**
* 讀取1M數(shù)據(jù)量的消息
* @param socket
* @throws IOException
*/
private static void acceptMessage(Socket socket) throws IOException {
InputStream messageIn = socket.getInputStream();
byte[] buf = new byte[1024];
int len = messageIn.read(buf);
System.out.println(new String(buf, 0, len));
socket.shutdownInput();
}
}
數(shù)據(jù)傳輸
服務(wù)端程序2
package com.loyotech.bigscreenbackend.socket;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @program big-screen-backend
* @description 網(wǎng)絡(luò)互聯(lián), 發(fā)送消息
* @author Rudolph Browne
* @create 19-1-12
*/
public class ServerSocket2 {
public static void main(String[] args) throws IOException {
// 暴露服務(wù), 端點(diǎn)地址: 本機(jī)IP和8888
try(ServerSocket server = new ServerSocket(8888);
Socket socket = server.accept()) {
System.out.println("與客戶端連接成功...");
sendFile(socket, new File("/home/harry/Desktop/Spring揭秘.pdf"));
}
}
/**
* 發(fā)送1M的消息
* @param socket
* @param fileDescriptor
* @throws IOException
*/
private static void sendFile(Socket socket, File fileDescriptor) throws IOException {
try(FileInputStream fileInputStream = new FileInputStream(fileDescriptor)) {
OutputStream packageOut = socket.getOutputStream();
byte[] buf = new byte[1024]; // 1M大小的緩沖區(qū)
int len = -1; // 每次讀文件流大小
while((len = fileInputStream.read(buf)) != -1) {
packageOut.write(buf, 0, len);
}
System.out.println("成功將文件"+ fileDescriptor.getAbsolutePath()
+ "發(fā)送至" + socket.getInetAddress().getHostAddress());
socket.shutdownOutput();
}
}
/**
* 讀取1M數(shù)據(jù)量的消息
* @param socket
* @throws IOException
*/
private static void acceptFile(Socket socket, File fileDescriptor) throws IOException {
try(FileOutputStream fileOutputStream = new FileOutputStream(fileDescriptor)) {
InputStream pacakageIn = socket.getInputStream();
byte[] buf = new byte[1024];
int len = -1;
while ((len = pacakageIn.read(buf)) != -1){
fileOutputStream.write(buf, 0, len);
}
socket.shutdownInput();
}
System.out.println("從 " + socket.getInetAddress().getHostAddress() + " 接收數(shù)據(jù)," +
"數(shù)據(jù)寫入成功,存儲(chǔ)位置: " + fileDescriptor.getAbsolutePath());
}
}
客戶端程序2
package com.loyotech.bigscreenbackend.socket;
import java.io.*;
import java.net.Socket;
/*
* @program big-screen-backend
* @description
* @author Rudolph Browne
* @create 19-1-12
*/
public class ClientSocket2 {
public static void main(String[] args) throws IOException {
try(Socket socket = new Socket("192.168.0.104", 8888)) {
acceptFile(socket, new File("/media/harry/OS/Users/Rudolph Browne/WorkingSpace/揭秘.pdf"));
}
}
/**
* 發(fā)送1M的消息
* @param socket
* @param fileDescriptor
* @throws IOException
*/
private static void sendFile(Socket socket, File fileDescriptor) throws IOException {
try(FileInputStream fileInputStream = new FileInputStream(fileDescriptor)) {
OutputStream packageOut = socket.getOutputStream();
byte[] buf = new byte[1024]; // 1M大小的緩沖區(qū)
int len = -1; // 每次讀文件流大小
while((len = fileInputStream.read(buf)) != -1) {
packageOut.write(buf, 0, len);
}
System.out.println("成功將文件"+ fileDescriptor.getAbsolutePath()
+ "發(fā)送至" + socket.getInetAddress().getHostAddress());
socket.shutdownOutput();
}
}
/**
* 讀取1M數(shù)據(jù)量的消息
* @param socket
* @throws IOException
*/
private static void acceptFile(Socket socket, File fileDescriptor) throws IOException {
try(FileOutputStream fileOutputStream = new FileOutputStream(fileDescriptor)) {
InputStream pacakageIn = socket.getInputStream();
byte[] buf = new byte[1024];
int len = -1;
while ((len = pacakageIn.read(buf)) != -1){
fileOutputStream.write(buf, 0, len);
}
socket.shutdownInput();
}
System.out.println("從" + socket.getInetAddress().getHostAddress() + "接收數(shù)據(jù)," +
"數(shù)據(jù)寫入成功,存儲(chǔ)位置: " + fileDescriptor.getAbsolutePath());
}
}
支持多用戶并發(fā)上傳下載文件
做法是使用多線程, 非NIO版本
服務(wù)端程序3
package com.loyotech.bigscreenbackend.socket;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @program big-screen-backend
* @description 支持多用戶下載文件
* @author Rudolph Browne
* @create 19-1-12
*/
public class ServerSocket3 {
public static void main(String[] args) throws IOException {
// 暴露服務(wù), 端點(diǎn)地址: 本機(jī)IP和8888
try(ServerSocket server = new ServerSocket(8888)){
while (true) {
Socket socket = server.accept();
System.out.println("與客戶端 " + socket.getInetAddress().getHostAddress() + " 連接成功...");
new Thread(new MyDownloadFileSocketHelper(socket,
new File("/home/harry/Desktop/Spring揭秘.pdf"))).start();
}
}
}
/**
* 發(fā)送1M的消息
* @param socket
* @param fileDescriptor
* @throws IOException
*/
private static void sendFile(Socket socket, File fileDescriptor) throws IOException {
try(FileInputStream fileInputStream = new FileInputStream(fileDescriptor)) {
OutputStream packageOut = socket.getOutputStream();
byte[] buf = new byte[1024]; // 1M大小的緩沖區(qū)
int len = -1; // 每次讀文件流大小
while((len = fileInputStream.read(buf)) != -1) {
packageOut.write(buf, 0, len);
}
System.out.println("成功將文件"+ fileDescriptor.getAbsolutePath()
+ "發(fā)送至" + socket.getInetAddress().getHostAddress());
socket.shutdownOutput();
}
}
private static class MyDownloadFileSocketHelper implements Runnable {
private Socket socket;
private File fileDescriptor;
public MyDownloadFileSocketHelper(Socket socket, File fileDescriptor){
this.socket = socket;
this.fileDescriptor = fileDescriptor;
}
@Override
public void run() {
try {
sendFile(socket, fileDescriptor);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
客戶端程序3
package com.loyotech.bigscreenbackend.socket;
import java.io.*;
import java.net.Socket;
import java.time.Instant;
/*
* @program big-screen-backend
* @description 支持多用戶下載文件
* @author Rudolph Browne
* @create 19-1-12
*/
public class ClientSocket3 {
public static void main(String[] args) throws IOException {
try(Socket socket = new Socket("192.168.0.104", 8888)) {
acceptFile(socket, new File("/media/harry/OS/Users/Rudolph Browne/WorkingSpace/揭秘" + Instant.now() + ".pdf"));
}
}
/**
* 讀取1M數(shù)據(jù)量的消息
* @param socket
* @throws IOException
*/
private static void acceptFile(Socket socket, File fileDescriptor) throws IOException {
try(FileOutputStream fileOutputStream = new FileOutputStream(fileDescriptor)) {
InputStream pacakageIn = socket.getInputStream();
byte[] buf = new byte[1024];
int len = -1;
while ((len = pacakageIn.read(buf)) != -1){
fileOutputStream.write(buf, 0, len);
}
socket.shutdownInput();
}
System.out.println("從" + socket.getInetAddress().getHostAddress() + "接收數(shù)據(jù)," +
"數(shù)據(jù)寫入成功,存儲(chǔ)位置: " + fileDescriptor.getAbsolutePath());
}
}