网络编程服务端与客户端半关闭的流

最常见的客户端:

    浏览器 :IE。

最常见的服务端:

    服务器:Tomcat。

浏览器请求: 为什么要发送请求? 没有请求,服务器不知道你需要什么页面,什么内容,你能接受什么信息。

请求: 发送的请求是:请求消息 请求头 + 空行 + 请求体

请求消息头 属性名:属性值

GET /myweb/1.html HTTP/1.1 第一行请求行: 请求方式 请求的资源路径 协议版本

Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash,

application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */ *

Accept-Language: zh-cn,zu;q=0.5

Accept-Encoding: gzip, deflate

User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.2)

Host: 192.168.1.100:9090

Connection: Keep-Alive

//空行

//请求体。

服务器应答 //服务端发回应答消息。

HTTP/1.1 200 OK //应答行,http的协议版本 应答状态码 应答状态描述信息

应答消息属性信息。 属性名:属性值

Server: Apache-Coyote/1.1

ETag: W/"199-1323480176984"

Last-Modified: Sat, 10 Dec 2011 01:22:56 GMT

Content-Type: text/html

Content-Length: 199

Date: Fri, 11 May 2012 07:51:39 GMT

Connection: close

//空行

//应答体。

<html>

    <head>

        <title>这是我的网页</title>

    </head>

    <body>

        <h1>欢迎光临</h1>

        <font size='5' color="red">这是一个tomcat服务器中的资源。是一个html网页。</font>

    </body>

</html>

// 自定义浏览器;模拟浏览器

    public static void main(String[] args) throws UnknownHostException, IOException {

       

// 访问 192.168.1.100:8080 服务器

        Socket s = new Socket("192.168.1.100",8080);

        //访问http://192.168.1.100:8080/myweb/1.html

        //模拟浏览器,给tomcat服务端发送符合http协议的请求消息。告诉浏览器我需要什么。

        PrintWriter out = new PrintWriter(s.getOutputStream(),true);

        out.println("GET /myweb/1.html HTTP/1.1");

        out.println("Accept: */*");

        out.println("Host: 192.168.1.100:8080"); //访问的主机

        out.println("Connection: close");

        out.println();

       

        InputStream in = s.getInputStream();

       

        byte[] buf = new byte[1024];

        int len = in.read(buf);

       

        String str =new String(buf,0,len);

        System.out.println(str);

       

        s.close();

    }

自定义服务器: 模拟服务器

public class MyTomcat {

    /**

     * @param args

     * @throws IOException

     */

    public static void main(String[] args) throws IOException {

         // 建立服务器socket 明确端口

        ServerSocket ss = new ServerSocket(9090);

    while(true) {

        多线程并发访问。

         Socket s= ss.accept();

new Thread(new Threadtext(s)).start();

     //    http://115.158.64.36:9090/

}

    }

}

/线程任务

class Threadtext implements Runnable{

    Socket s;

    public Threadtext(Socket ss) {

        super();

        this.s = ss;

    }

    public void run() {

        String ip = s.getInetAddress().getHostAddress();   

        try {

     / 获得浏览器请求

        InputStream in = s.getInputStream();

       

        byte[] buf = new byte[1024];

       

        int len = in.read(buf);

        String text = new String(buf,0,len);

        System.out.println(ip);

        System.out.println("*********************");

        System.out.println(text);

       

       

        //给客户端一个反馈信息。

        PrintWriter out = new PrintWriter(s.getOutputStream(),true);

        out.println("<font color='red' size='50'> 109 的大帅比 109 的大帅比 109 的大帅比 109 的大帅比 109 的大帅比 109 的大帅比</font>");

       

        s.close();

        }catch(Exception E) {

           

        }

       

       

    }

}

浏览器模拟

URL 对象与 URLConnection对象: 类 URL 代表一个统一资源定位符,它是指向互联网“资源”的指针。

类 URLConnection 将 连接 封装成了对象:java中内置的可以解析的具体协议的对象 + socket.封装为对象。解析URL并发送URL请求。

                         public static void main(String[] args) throws IOException {

        String str_url = "http://192.168.1.100:8080/myweb/1.html";

    类 URL 代表一个统一资源定位符,它是指向互联网“资源”的指针 ,此处并没有连接

        URL url = new URL(str_url); 

//      System.out.println("getProtocol:"+url.getProtocol());

//      System.out.println("getHost:"+url.getHost());

//      System.out.println("getPort:"+url.getPort());

//      System.out.println("getFile:"+url.getFile());

//      System.out.println("getPath:"+url.getPath());

//      System.out.println("getQuery:"+url.getQuery());

       

//      InputStream in = url.openStream();

       

     获取url对象的Url连接器对象。将连接封装成了对象:java中内置的可以解析的具体协议的对象+socket.

     建立socket 并发送请求信息。

        URLConnection conn = url.openConnection();

       

//      String value = conn.getHeaderField("Content-Type");

//      System.out.println(value);

       

//      System.out.println(conn);

        //sun.net.www.protocol.http.HttpURLConnection:http://192.168.1.100:8080/myweb/1.html

       

        InputStream in = conn.getInputStream();

       

        byte[] buf = new byte[1024];

        int len = in.read(buf);

        String text = new String(buf,0,len);       

        System.out.println(text);

       

        in.close();

    }

 服务端

public class Server
{
	public static void main(String[] args)
		throws IOException
	{
		// 创建一个ServerSocket,用于监听客户端Socket的连接请求
		ServerSocket ss = new ServerSocket(30000);
		// 采用循环不断接受来自客户端的请求
		while (true)
		{
			// 每当接受到客户端Socket的请求,服务器端也对应产生一个Socket
			Socket s = ss.accept();
			// 将Socket对应的输出流包装成PrintStream
			PrintStream ps = new PrintStream(s.getOutputStream());
			// 进行普通IO操作
			ps.println("您好,您收到了服务器的新年祝福!");
			// 关闭输出流,关闭Socket
			ps.close();
			s.close();
		}
	}
}

客户端

public class Client
{
	public static void main(String[] args)
		throws IOException
	{
		Socket socket = new Socket("127.0.0.1" , 30000);   // ①
		// 将Socket对应的输入流包装成BufferedReader
		BufferedReader br = new BufferedReader(
		new InputStreamReader(socket.getInputStream()));
		// 进行普通IO操作
		String line = br.readLine();
		System.out.println("来自服务器的数据:" + line);
		// 关闭输入流、socket
		br.close();
		socket.close();
	}
}

半关闭的Socket

public static void main(String[] args)
		throws Exception
	{
		ServerSocket ss = new ServerSocket(30000);
		Socket socket = ss.accept();
		PrintStream ps = new PrintStream(socket.getOutputStream());
		ps.println("服务器的第一行数据");
		ps.println("服务器的第二行数据");
		// 关闭socket的输出流,表明输出数据已经结束
		socket.shutdownOutput();
		// 下面语句将输出false,表明socket还未关闭。
		System.out.println(socket.isClosed());
		Scanner scan = new Scanner(socket.getInputStream());
		while (scan.hasNextLine())
		{
			System.out.println(scan.nextLine());
		}
		scan.close();
		socket.close();
		ss.close();
	}
  • URLConnection 和socket都是一站式的响应,socket当关闭流以后socket也将关闭,不适合保持持久通信的状态,只适用于请求一次相应一次。当相应完成以后,socket也将关闭。而URLConnection 也式通样。

猜你喜欢

转载自blog.csdn.net/qq_38003454/article/details/83241961
今日推荐