java socket 保存的图片为什么打不开?问题出在哪?求大神指点
用socket保存一个网页上的验证码图片到本地,打开后显示 无法预览 是为什么啊?代码如下:import java.net.*;
import java.io.*;
public class HTTPClient{
String host="reg.email.163.com";
int port=80;
Socket socket;
public void createSocket()throws Exception{
socket=new Socket(host, port);
}
public void communicate()throws Exception{
StringBuffer sb=new StringBuffer("GET /unireg/call.do?cmd=register.verifyCode&env=369398958183&t=1351924543383 HTTP/1.1\r\n");
sb.append("Host: reg.email.163.com\r\n");
sb.append("Accept: */*\r\n");
sb.append("Accept-Language: zh-cn\r\n");
sb.append("Accept-Encoding: gzip, deflate\r\n");
sb.append("User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)\r\n");
sb.append("Connection: Keep-Alive\r\n\r\n");
OutputStream socketOut=socket.getOutputStream();
socketOut.write(sb.toString().getBytes());
socket.shutdownOutput();
InputStream socketIn=socket.getInputStream();
ByteArrayOutputStream buffer=new ByteArrayOutputStream();
byte[] buff=new byte[1024];
int len=-1;
while((len=socketIn.read(buff))!=-1){
buffer.write(buff,0,len);
}
socket.close();
FileOutputStream fos=new FileOutputStream(new File("c:\\1.jpg"));
OutputStreamWriter osw=new OutputStreamWriter(fos);
osw.write((new String(buffer.toByteArray())).split("\r\n\r\n")[1]);
osw.flush();
osw.close();
}
public static void main(String arch[])throws Exception{
HTTPClient client=new HTTPClient();
client.createSocket();
client.communicate();
}
}
求指点!!!
----------------解决方案--------------------------------------------------------
回复 楼主 goddy
各位大神、高手、英雄,走过路过的,指点一下!!! ----------------解决方案--------------------------------------------------------
这是返回的部分数据
HTTP/1.1 200 OK
Server: nginx
Date: Sat, 03 Nov 2012 08:10:52 GMT
Content-Type: image/jpeg;charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Set-Cookie: JSESSIONID=5CF3B05BC9422512233F4431C19E6210; Path=/unireg
pragma: NO-cache
Cache-Control: no-cache
Expries: Thu, 01 Jan 1970 00:00:00 GMT
Content-Language: zh-CN
X-Cache: from gzip141-192.163.com
你的代码并没有解析这些数据,它们不是图片数据。
另外http链接可以使用HttpURLConnection 进行传输数据,如果非要用socket那就要自己解析返回的数据。
----------------解决方案--------------------------------------------------------
回复 3楼 shellingford
有些图片链接是https的,怎么用HttpURLConnection?指点一下 ----------------解决方案--------------------------------------------------------
回复 3楼 shellingford
osw.write((new String(buffer.toByteArray())).split("\r\n\r\n")[1]);就是将响头和正文分开了啊
----------------解决方案--------------------------------------------------------
人呢?
----------------解决方案--------------------------------------------------------
程序代码:
public class ServletUtil {
public static HttpURLConnection getHttpsURLConnection(String surl) throws NoSuchAlgorithmException, KeyManagementException, IOException{
URL url=new URL(surl);
if(surl.toLowerCase().startsWith("https")){
SSLContext sc = null;
TrustAnyHostnameVerifier verifier=null;
sc = SSLContext.getInstance("SSL");
sc.init(null, new TrustManager[] { new TrustAnyTrustManager() },
new java.security.SecureRandom());
verifier = new TrustAnyHostnameVerifier();
HttpsURLConnection httpsCon = (HttpsURLConnection) url.openConnection();
httpsCon.setSSLSocketFactory(sc.getSocketFactory());
httpsCon.setHostnameVerifier(verifier);
return (HttpURLConnection)httpsCon;
}else{
return (HttpURLConnection) url.openConnection();
}
}
}
class TrustAnyTrustManager implements X509TrustManager {
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[] {};
}
}
class TrustAnyHostnameVerifier implements HostnameVerifier {
public boolean verify(String hostname, SSLSession session) {
return true;
}
}
public static HttpURLConnection getHttpsURLConnection(String surl) throws NoSuchAlgorithmException, KeyManagementException, IOException{
URL url=new URL(surl);
if(surl.toLowerCase().startsWith("https")){
SSLContext sc = null;
TrustAnyHostnameVerifier verifier=null;
sc = SSLContext.getInstance("SSL");
sc.init(null, new TrustManager[] { new TrustAnyTrustManager() },
new java.security.SecureRandom());
verifier = new TrustAnyHostnameVerifier();
HttpsURLConnection httpsCon = (HttpsURLConnection) url.openConnection();
httpsCon.setSSLSocketFactory(sc.getSocketFactory());
httpsCon.setHostnameVerifier(verifier);
return (HttpURLConnection)httpsCon;
}else{
return (HttpURLConnection) url.openConnection();
}
}
}
class TrustAnyTrustManager implements X509TrustManager {
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[] {};
}
}
class TrustAnyHostnameVerifier implements HostnameVerifier {
public boolean verify(String hostname, SSLSession session) {
return true;
}
}
----------------解决方案--------------------------------------------------------
回复 7楼 shellingford
非常好用,谢谢;顺便问一下HttpClient怎么发送https 请求?非常好用,谢谢;顺便问一下HttpClient怎么发送https 请求? ----------------解决方案--------------------------------------------------------
URL url = new URL(...);
HttpURLConnection link = (HttpURLConnection)url.openConnection();
// 设置头信息:
link.setRequestProperty("...", "...");
link.setRequestProperty("...", "...");
link.setRequestProperty("...", "...");
...
// 默认使用GET方法,如果使用POST:
link.setRequestMethod("POST");
link.setDoOutput(true);
// 连接(如果在获取流的时候没有连接,则会自动连接,所以这句可以省略):
link.connect();
// 获得输入流:
InputStream in = link.getInputStream();
...
in.close();
// 获得输出流(POST):
OutputStream out = link.getOutputStream();
...
out.close();
[ 本帖最后由 lz1091914999 于 2012-11-6 23:47 编辑 ]
----------------解决方案--------------------------------------------------------