欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-06-30 18:20:58
...

 


最常见的客户端:

    浏览器 :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 也式通样。