package socket;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class Client
{
public static void main(String[] args) throws Exception
{
Socket client = new Socket("dlsw.baidu.com", 80);
client.setSoTimeout(10000);
StringBuilder sb = new StringBuilder();
// HTTP协议中的换行符为CRLF,即\r\n,每一行请求消息头都需要以其结尾
sb.append("GET /sw-search-sp/soft/2e/10849/wrar521sc_setup.1426841415.exe HTTP/1.1\r\n");
sb.append("Host: dlsw.baidu.com\r\n");
sb.append("Connection: keep-alive\r\n");
sb.append("Accept: */*\r\n");
sb.append("User-Agent: JavaSocket\r\n");
// 消息头结束需要单独一行CRLF
sb.append("\r\n");
OutputStream os = client.getOutputStream();
InputStream is = client.getInputStream();
os.write(sb.toString().getBytes("UTF-8"));
os.flush();
// 保存文件路径
File file = new File("D:/Setups/wrar521sc_setup.1426841415.exe");
FileOutputStream fos = new FileOutputStream(file);
String line = null;
long contentLength = 0;
// HTTP协议中的换行符为CRLF,即\r\n,读取到单独的一行\r\n意味着消息头读取完毕。
while (!"\r\n".equals(line))
{
line = readLine(is);
if (line.startsWith("Content-Length"))
{
contentLength = Long.parseLong(line.split(":")[1].trim());
}
System.out.print(line);
}
saveBody(is, contentLength, fos);
System.out.println("File download complete.");
// 应该在try-catch的finally块中关闭,为了减少篇幅写简单点。
client.close();
is.close();
fos.close();
}
/**
* 从socket的输入流中按行读取消息头
* @param is 输入流
* @return 每行字符串
* @throws Exception
*/
private static String readLine(InputStream is) throws Exception
{
List<Byte> lineBytes = new ArrayList<Byte>();
int readByte = 0;
while (true)
{
readByte = is.read();
lineBytes.add(new Byte((byte) readByte));
if (10 == readByte)
{
// \r\n 分别为13、10,读取到10意味着换行,跳出循环
break;
}
}
byte[] bytes = new byte[lineBytes.size()];
for (int i = 0; i < lineBytes.size(); i++)
{
bytes[i] = lineBytes.get(i).byteValue();
}
return new String(bytes);
}
/**
* 保存消息体的字节流到文件中。
* @param is socket的输入流
* @param contentLength response中返回的消息体长度
* @param fos 文件输出流
* @throws Exception
*/
private static void saveBody(InputStream is, long contentLength,
FileOutputStream fos) throws Exception
{
long totalRead = 0;
byte[] bytes = new byte[512];
while (totalRead < contentLength)
{
int read = is.read(bytes);
totalRead += read;
// 这里不能直接使用fos.write(bytes),因为即使除了最后一次,前面也不是每次读取的长度都为512(数组长度),一定要根据每次读取的长度写入输出流
fos.write(bytes, 0, read);
}
fos.flush();
}
}
Socket编程:下载文件
最新推荐文章于 2021-03-18 23:15:04 发布