码迷,mamicode.com
首页 > Web开发 > 详细

简单的Socket实现的http Server

时间:2015-09-07 19:54:15      阅读:214      评论:0      收藏:0      [点我收藏+]

标签:

代码下载地址  http://note.youdao.com/share/?id=1d28ee946720332255efc72c3e12a0da&type=note

参考 http://blog.csdn.net/u010687392/article/details/44649589

/**
 * 
 * @className: MainActivity
 * @description: 手机红外客户端:处理TV请求发射的红外码
 * @author: Administrator
 * @date: 2015年9月6日 上午9:40:13
 */
public class MainActivity extends Activity
{
    private TextView mInputText;
    ServerSocket server = null;
    Socket socket = null;
    private TextView mTitleText;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTitleText = (TextView) findViewById(R.id.title);
        mInputText = (TextView) findViewById(R.id.msg);
        initServiceData();
        mTitleText.setText("IP:" + getIp());
        
    }
    
    private String getIp() {
        WifiManager wifimanger = (WifiManager) getSystemService(WIFI_SERVICE);
        WifiInfo wifiinfo = wifimanger.getConnectionInfo();
        int i = wifiinfo.getIpAddress();
        return (i & 0xFF) + "." + ((i >> 8) & 0xFF) + "." + ((i >> 16) & 0xFF) + "." + (i >> 24 & 0xFF);
    }
    
    private void initServiceData() {
        
        new Thread()
        {
            @Override
            public void run() {
                
                try {
                    server = new ServerSocket(8888);//创建一个ServerSocket,并让Socket监听8888的端口
                    
                    // 调用ServerSocket的accept()方法,接受客户端所发送的请求,同时创建一个Socket对象
                    // 如果客户端没有发送数据,那么该线程就停滞不继续,也就是阻塞
                    while (true) {
                        socket = server.accept();
                        System.out.println("主机:" + socket.getInetAddress().getHostName() + ",IP:" + socket.getInetAddress().getHostAddress());//得到当前发送数据Socket对象的主机名和ip地址
                        
                        //读取客户端的消息
                        InputStream inputStream = socket.getInputStream();
                        BufferedInputStream bis = new BufferedInputStream(inputStream);
                        //byte[] b = new byte[inputStream.available()];
                        byte[] b = new byte[1024 * 2];
                        int len = -1;
                        final StringBuilder stringBuilder = new StringBuilder();
                        while ((len = bis.read(b)) != -1) {
                            String msg = new String(b, 0, len, "UTF-8");
                            System.out.println(msg);
                            stringBuilder.append(msg);
                            break;//一次只能读取2048个自己的请求数据, 当然也可以更加content lenght计算, 然后跳出循环. 注意.这里 read(b) 永远不会是-1 因为读取到输入流末尾之后, socket还是会尝试读取client的数据
                        }
                        
                        runOnUiThread(new Runnable()
                        {
                            @Override
                            public void run() {
                                HttpRequestParser httpRequestParser = new HttpRequestParser();
                                try {
                                    httpRequestParser.parseRequest(stringBuilder.toString());
                                    mInputText.append(stringBuilder.toString() + "\n=================\n\n");
                                    //mInputText.append(URLDecoder.decode(httpRequestParser.getMessageBody(), "UTF-8"));
                                    Log.d("TAG", "params is " + URLDecoder.decode(httpRequestParser.getMessageBody(), "UTF-8"));
                                    
                                }
                                catch (IOException e) {
                                    e.printStackTrace();
                                }
                                catch (HttpFormatException e) {
                                    e.printStackTrace();
                                }
                                
                            }
                        });
                        socket.shutdownInput();//结束读取
                        
                        //--------向客户端的返回信息-------------
                        OutputStream outputResult = socket.getOutputStream();
                        StringBuffer sb = new StringBuffer();
                        sb.append("HTTP/1.1 200 OK\r\n");
                        sb.append("Host: " + socket.getInetAddress().getHostName() + "\r\n");
                        sb.append("\r\n");
                        outputResult.write(sb.toString().getBytes());
                        outputResult.write("ok,received".getBytes());
                        outputResult.flush();
                        
                        bis.close();//关闭缓存输入流,注意,输入流input不需要关闭,因为它只是在Socket中得到输入流对象,并没有创建
                        
                        socket.close();//接收这个Socket的数据后释放资源,因为每一次客户端发送数据都会在服务端创建一个Socket对象,注意ServerSocket不应该关闭,因为这是服务器ServerSocket对象,关闭了客户端就不能发送数据了
                        socket = null;
                        
                    }
                    
                }
                catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }.start();
        
    }
}



Http报文解析类
/**
 * Class for HTTP request parsing as defined by RFC 2612:
 * 
 * Request = Request-Line ; Section 5.1 (( general-header ; Section 4.5 |
 * request-header ; Section 5.3 | entity-header ) CRLF) ; Section 7.1 CRLF [
 * message-body ] ; Section 4.3
 * 
 * @author izelaya
 *
 */
public class HttpRequestParser
{
    
    private String _requestLine;
    private HashMap<String, String> _requestHeaders;
    private StringBuffer _messagetBody;
    
    public HttpRequestParser() {
        _requestHeaders = new HashMap<String, String>();
        _messagetBody = new StringBuffer();
    }
    
    /**
     * Parse and HTTP request.
     * 
     * @param request
     *            String holding http request.
     * @throws IOException
     *             If an I/O error occurs reading the input stream.
     * @throws HttpFormatException
     *             If HTTP Request is malformed
     */
    public void parseRequest(String request) throws IOException, HttpFormatException {
        if (TextUtils.isEmpty(request)) {
            return;
        }
        BufferedReader reader = new BufferedReader(new StringReader(request));
        
        setRequestLine(reader.readLine()); // Request-Line ; Section 5.1
        
        String header = reader.readLine();
        while (header.length() > 0) {
            appendHeaderParameter(header);
            header = reader.readLine();
        }
        
        String bodyLine = reader.readLine();
        while (bodyLine != null) {
            appendMessageBody(bodyLine);
            bodyLine = reader.readLine();
        }
        
    }
    
    /**
     * 
     * 5.1 Request-Line The Request-Line begins with a method token, followed by
     * the Request-URI and the protocol version, and ending with CRLF. The
     * elements are separated by SP characters. No CR or LF is allowed except in
     * the final CRLF sequence.
     * 
     * @return String with Request-Line
     */
    public String getRequestLine() {
        return _requestLine;
    }
    
    private void setRequestLine(String requestLine) throws HttpFormatException {
        if (requestLine == null || requestLine.length() == 0) {
            throw new HttpFormatException("Invalid Request-Line: " + requestLine);
        }
        _requestLine = requestLine;
    }
    
    private void appendHeaderParameter(String header) throws HttpFormatException {
        int idx = header.indexOf(":");
        if (idx == -1) {
            throw new HttpFormatException("Invalid Header Parameter: " + header);
        }
        _requestHeaders.put(header.substring(0, idx), header.substring(idx + 1, header.length()));
    }
    
    /**
     * The message-body (if any) of an HTTP message is used to carry the
     * entity-body associated with the request or response. The message-body
     * differs from the entity-body only when a transfer-coding has been
     * applied, as indicated by the Transfer-Encoding header field (section
     * 14.41).
     * 
     * @return String with message-body
     */
    public String getMessageBody() {
        return _messagetBody.toString();
    }
    
    private void appendMessageBody(String bodyLine) {
        _messagetBody.append(bodyLine).append("\r\n");
    }
    
    /**
     * For list of available headers refer to sections: 4.5, 5.3, 7.1 of RFC
     * 2616
     * 
     * @param headerName
     *            Name of header
     * @return String with the value of the header or null if not found.
     */
    public String getHeaderParam(String headerName) {
        return _requestHeaders.get(headerName);
    }
    
    public class HttpFormatException extends Exception
    {
        
        private static final long serialVersionUID = 1L;
        
        public HttpFormatException(String string) {}
        
    }
}



简单的Socket实现的http Server

标签:

原文地址:http://my.oschina.net/sfshine/blog/502455

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!