代码转自:http://www.cnblogs.com/sliencer/archive/2012/03/11/2390034.html
昨天在stackoverflow上找代码,找到的都没法运行,不是消息头缺少/r/n或者消息体与内容之间没有空一行,就是运行出来白板或者报错。今天用百度找,果断还是国内的大神靠谱,贴代码:
package org.vegbird;
import java.io.*;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.net.*;
public class TestSocket_Server {
class MySocketHandler implements Runnable {
@Override
public void run() {
try {
println("Incoming found@" + s0.getPort());
HandleIncomingSocket(s0);
} catch (Exception e) {
println("Exception: " + e.getMessage());
} finally {
try {
println("Closing Socket.");
s0.close();
} catch (Exception e2){}
println("Socket closed!");
}
}
public Socket s0;
}
public static void main(String[] args) throws Exception {
new TestSocket_Server().Run();
}//main()
public void Run() throws Exception{
ServerSocket ss = new ServerSocket(80);
ExecutorService service= Executors.newCachedThreadPool();
for (int i=0;i<10;i++) {
printf("%d/10: Waiting incoming connection...\n", i+1);
Socket s0=ss.accept();
MySocketHandler receiver = new MySocketHandler();
receiver.s0 = s0;
service.execute(receiver);
}
println("shutdown now");
service.shutdown();
service.awaitTermination(10, TimeUnit.SECONDS);
println("Quit now");
}
public static void HandleIncomingSocket(Socket s) throws Exception {
InputStream in=s.getInputStream();
byte[] buffer = new byte[1024*1024*10];
File fTemp = File.createTempFile("temp", ".txt");
printf("Temp file %s created\n", fTemp.getAbsolutePath());
printf("IsClosed = %s, IsConnected=%s, IsInputShutdown=%s, IsOutputShutdown=%s\n"
, s.isClosed(), s.isConnected(), s.isInputShutdown(), s.isOutputShutdown());
printf("available=%d\n", in.available());
int nReads = 0;
if(in.available() >0)
nReads = in.read(buffer);
while(nReads>0) {
FileOutputStream fs = new FileOutputStream(fTemp,true);
fs.write(buffer, 0, nReads);
fs.flush();
fs.close();
printf("IsClosed = %s, IsConnected=%s, IsInputShutdown=%s, IsOutputShutdown=%s\n"
, s.isClosed(), s.isConnected(), s.isInputShutdown(), s.isOutputShutdown());
nReads = 0;
if (in.available()>0)
nReads = in.read(buffer);
}
printf("%d bytes read from client\n", fTemp.length());
StringBuilder bld = new StringBuilder();
bld.append(String.format("Received %d bytes
\n", fTemp.length()));
bld.append("Here's the text I got, pls. verify
\n");
if (fTemp.length()>0) {
Scanner sc=new Scanner(fTemp);
while(sc.hasNextLine()) {
String line = sc.nextLine();
line +="
\r\n";
bld.append(line);
printf(line);
}
sc.close();
}
OutputStream out = s.getOutputStream();
byte[] content=bld.toString().getBytes();
int nLen=content.length;
bld = new StringBuilder();
bld.append("HTTP/1.0 200 OK\r\n");
bld.append("Last-Modified: Sat, 10 Mar 2012 14:42:12 GMT\r\n");
bld.append("Accept-Ranges: bytes\r\n");
bld.append("Content-Type: text/html\r\n");
bld.append("Date: Sat, 10 Mar 2012 14:46:19 GMT\r\n");
bld.append("Server: TestServer\r\n");
bld.append("Expires: Sat, 10 Mar 1900 14:47:19 GMT\r\n");
bld.append(String.format("Content-Length: %d\r\n", nLen));
bld.append("Connection: close\r\n");
bld.append("\r\n");
out.write(bld.toString().getBytes());
out.write(content);
out.flush();
out.close();
}
private static void printf(String format, Object... args) {
System.out.print(Thread.currentThread().getId());
System.out.print('\t');
if (args == null || args.length == 0) {
System.out.print(format);
} else {
System.out.printf(format, args);
}
}
private static void println(String msg) {
System.out.print(Thread.currentThread().getId());
System.out.print('\t');
System.out.println(msg);
}
}
这段代码的精髓就在handler中的try catch中,因为浏览器向服务器发送http的请求时实际上是发送了三个socket请求,其中的2个是不发送任何数据的,而且建立完链接后在很短的时间内就断开了链接,当服务器端使用getOutPutStream时会抛出异常,所以要catch住这个异常,不予处理。而对实际会发送数据的链接进行处理。