(1)如何使用Socket和ServerSocket?
- Socket
部分构造方法
Socket()
Socket(InetAddress address, int port)
Socket(InetAddress address, int port, InetAddress localAddr, int localPort)
Socket 的构造方法中除了无参的构造方法,其他方法都会尝试与给定的服务器地址建立连接,失败会抛出异常。InetAddress 类用来表示一个 ip 地址。
部分方法
bind(SocketAddress bindpoint) //绑定 Socket 到指定的地址
connect(SocketAddress endpoint) //连接至指定的服务器
getInputStream()
getOutputStream()
getInputStream() 跟 getOutputStream() 方法获取的输入输出流可以用来跟服务器通信,比较重要的方法。
- ServerSocket
部分构造方法
ServerSocket()
ServerSocket(int port)
可以在创建 ServerSocket 的时候指定监听的端口,也可以在之后绑定。
部分方法
accept()
bind(SocketAddress endpoint)
bind() 方法使 ServerSocket 绑定指定地址。
accept() 方法返回一个连接队列中的一个 Socket。
一个很简单的多线程例子
public class App {
public static void main(String[] args) {
Thread client = new Thread(new Client());
Thread server = new Thread(new Server());
client.start();
server.start();
}
}
public class Client implements Runnable {
@Override
public void run() {
Socket client;
try {
client = new Socket("127.0.0.1", 3666);
System.out.println("客户端链接---");
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
Scanner scan = new Scanner(System.in);
while(true) {
out.write(scan.nextLine() + "\n");
out.flush();
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class Server implements Runnable {
@Override
public void run() {
ServerSocket socket;
SocketAddress address;
try {
address = new InetSocketAddress("127.0.0.1", 3666);
socket = new ServerSocket();
socket.bind(address);
System.out.println("服务端启动服务---> ip: " + socket.getLocalSocketAddress() + " port: " + socket.getLocalPort());
Socket client = socket.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
while(true) {
System.out.println("客户端输入---> " + in.readLine());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
(2)如何通过Socket发送和接收文件?
相当于将文件用字节流来传输,跟传文本类似
服务器端代码
ServerSocket socket;
SocketAddress address;
String filePath = "E:\\demo\\test.txt";
File file = new File(filePath);
try {
BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
address = new InetSocketAddress("127.0.0.1", 3666);
socket = new ServerSocket();
socket.bind(address);
System.out.println("服务端启动服务---> ip: " + socket.getLocalSocketAddress() + " port: " + socket.getLocalPort());
Socket client = socket.accept();
System.out.println("客户端连接成功!开始传输---");
DataOutputStream out = new DataOutputStream(client.getOutputStream());
byte[] b = new byte[1024];
while (in.read(b, 0, b.length) != -1) {
out.write(b);
}
out.flush();
System.out.println("传输完成!");
in.close();
out.close();
client.close();
} catch (IOException e) {
e.printStackTrace();
}
客户端代码
Socket client;
String filePath = "E:\\demo\\test2.txt";
File file = new File(filePath);
try {
client = new Socket("127.0.0.1", 3666);
System.out.println("客户端链接---");
DataInputStream in = new DataInputStream(client.getInputStream());
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file));
byte[] b = new byte[1024];
while (in.read(b, 0, b.length) != -1) {
out.write(b);
}
out.flush();
System.out.println("客户端接收完成!");
in.close();
out.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
(3)如何使用URLConnection下载一个文件?
java.net.URLConnection 类是一个抽象类,我们可以通过 URL 类的 openConnection 获取 URLConnection 的实现类。
URLConnection 可以设置不同的请求方式,如常见的 get、post 方法等。头部信息也有很多对应的方法设置,如
- setAllowUserInteraction
- setDoInput
- setDoOutput
- setIfModifiedSince
setUseCaches
还有一个通用的设置方法
setRequestProperty
下载文件时,我们通过 getInputStream() 方法获取输入流,将下载的数据写入文件
一个很简单的例子
public void download(String urlPath, String directory) {
URL url;
try {
url = new URL(urlPath);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.connect();
int fileLength = conn.getContentLength();
String filePath = url.getPath();
String fileName = filePath.substring(filePath.lastIndexOf("/") + 1);
System.out.println("文件大小:" + fileLength);
File file = new File(directory + File.separator + fileName);
if(!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
System.out.println("下载位置:" + file.getPath());
BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
byte[] b = new byte[1024];
int size = 0;
int downloadLength = 0;
while ((size = bis.read(b)) != -1) {
bos.write(b, 0, size);
downloadLength += size;
//System.out.println("已下载:" + downloadLength * 100 / fileLength + "%"); //打印下载百分比
}
bos.flush();
bos.close();
bis.close();
conn.disconnect();
} catch (MalformedURLException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}