网络编程(自定义浏览器-Tomcat服务器)

本文通过两个Java程序演示了如何模拟HTTP请求与响应的过程。首先通过Server程序监听特定端口并接收来自客户端的HTTP请求,然后使用Client2程序向该端口发送HTTP请求并展示服务器返回的响应信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


//一、获取客户端HTTP协议
//1、模拟http请求,先开启一个serverSocket服务,开启下面类Server.main()方法
//2、然后开启浏览器,输入http://127.0.0.1:10002
//在服务器窗口即打印出
//GET / HTTP/1.1
//Accept: */*
//Accept-Language: zh-cn
//User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.
//0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Cent
//er PC 6.0; .NET4.0C; .NET4.0E)
//Accept-Encoding: gzip, deflate
//Host: 127.0.0.1:10002
//Connection: Keep-Alive

import java.net.*;
import java.io.*;
class Server
{
	public static void main(String[] args) throws Exception
	{
		final ServerSocket server = new ServerSocket(10002);
		
		while(true)
		{
			final Socket socket = server.accept();
			new Thread(new Runnable()
			{
				public void run()
				{
					try
					{
						String ip = socket.getInetAddress().getHostAddress();
						System.out.println(ip + ".....connected");

						BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
						String line = null;
						while((line = br.readLine())!=null)
						{
							System.out.println(line);
						}

					}
					catch (Exception e)
					{
						e.printStackTrace();
						System.out.println("服务器有问题");
					}finally
					{	
						System.out.println("finally");
						if(socket !=null)
							try
							{
								socket.close();
							}
							catch (Exception e)
							{
								System.out.println("socket 关闭失败");
							}
					}
					
				}
			}).start();
		}
	}
}



二、获取服务器返回的http协议
//1、开启本地的tomcat服务
//2、将下面Client2中第一句代码的端口改为 tomcat的端口,运行Client2的main()
//即可获取
/*
HTTP/1.1 505 HTTP Version Not Supported
Server: Apache-Coyote/1.1
Date: Mon, 26 May 2014 05:58:58 GMT
Connection: close
*/

class Client2
{
	public static void main(String[] args) throws Exception
	{
		Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),10002);
		

		PrintWriter pw = new PrintWriter(socket.getOutputStream(),true);
		pw.println("#break");				
		pw.println("GET / HTTP/1.1");
		pw.println("Accept: */*");
		pw.println("Accept-Language: zh-cn");
		pw.println("Accept-Encoding: gzip, deflate");
		pw.println("Host: 127.0.0.1:10002");
		pw.println("Connection: closed");
		pw.println();
		pw.println();
		pw.println("#break");
		

		BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		String line = null;
		while((line = br.readLine())!=null)
		{
			System.out.println(line);
		}
		socket.close();
		
		
	}
}



//三、模拟http协议发送、与接收
//开启Server2 Client2  即模拟实现


class Server2
{
	public static void main(String[] args) throws Exception
	{
		final ServerSocket server = new ServerSocket(10002);
		

		while(true)
		{
			final Socket socket = server.accept();

			new Thread(new Runnable()
			{
				public void run()
				{
					
					try
					{
						String ip = socket.getInetAddress().getHostAddress();
						System.out.println(ip + ".....connected");

						BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
						String line = null;
						String breakPoint = br.readLine();


						while((line = br.readLine())!=null)
						{	
							if(breakPoint.equals(line))
								break;
							else
								System.out.println(line);
						}

						PrintWriter pw = new PrintWriter(socket.getOutputStream(),true);
						pw.println("HTTP/1.1 505 HTTP Version Not Supported");
						pw.println("Server: Apache-Coyote/1.1");
						pw.println("Date: Mon, 26 May 2014 05:58:58 GMT");
						pw.println("Connection: close");

					}
					catch (Exception e)
					{
						e.printStackTrace();
						System.out.println("服务器有问题");
					}finally
					{	
						if(socket !=null)
							try
							{
								socket.close();
							}
							catch (Exception e)
							{
								System.out.println("socket 关闭失败");
							}

					}
					
				}
			}).start();	
		}

		

	}
}


网络编程,当然要用到Windows Socket(套接字)技术。Socket相关的操作由一系列API函数来完成,比如socket、bind、listen、connect、accept、send、sendto、recv、recvfrom等。调用这些API函数有一定的先后次序,有些函数的参数还比较复杂,对于开发者来说,不是很好用。于是,微软的MFC提供了两个类:CAsyncSocket和CSocket,极大地方便了Socket功能的使用。   CAsyncSocket类在较低层次上封装了Windows Socket API,并且通过内建一个(隐藏的)窗口,实现了适合Windows应用的异步机制(Windows Socket API默认情况下工作在阻塞模式,不方便直接在消息驱动的Windows程序上使用)。CSocket类从CAsyncSocket类派生,进一步简化了Socket功能的应用。不过很遗憾,正因为这两个类都内建了一个窗口,它们并不是线程安全的(thread-safe);如果要在多线程环境下应用Socket功能,建议自行封装Socket API函数。 基于TCP的socket编程的服务器端程序流程如下: 1、创建套接字 2、将套接字绑定到一个本地地址和端口号上(bind) 3、将套接字设为监听模式,准备接受客户请求(listen) 4、等待客户请求,请求到来时接受请求,建立链接,并返回 一个新的基于此次通信的套接字(accept) 5、用返回的套接字和客户端进行通信(send、recv) 6、返回,等待另一客户请求 7、关闭套接字 基于TCP的socket编程的客户端程序流程如下: 1、创建套接字 2、向服务器端发送请求(connect) 3、和服务器端进行通信(send、recv) 4、关闭套接字 基于UDP的socket编程的服务器端程序流程如下: 1、创建套接字 2、将套接字绑定到本地地址和端口号上(bind) 3、等待接收数据(recvfrom) 4、关闭套接字 基于UDP的socket编程的客户端程序流程如下: 1、创建套接字 2、和服务器端进行通信(sendto) 3、关闭套接字 异步方式指的是发送方不等接收方响应,便接着发下个数据包的通信方式;而同步指发送方发出数据后,等收到接收方发回的响应,才发下一个数据包的通信方式。   阻塞套接字是指执行此套接字的网络调用时,直到成功才返回,否则一直阻塞在此网络调用上,比如调用recv()函数读取网络缓冲区中的数据,如果没有数据到达,将一直挂在recv()这个函数调用上,直到读到一些数据,此函数调用才返回;而非阻塞套接字是指执行此套接字的网络调用时,不管是否执行成功,都立即返回。比如调用recv()函数读取网络缓冲区中数据,不管是否读到数据都立即返回,而不会一直挂在此函数调用上。在实际Windows网络通信软件开发中,异步非阻塞套接字是用的最多的。平常所说的C/S(客户端/服务器)结构的软件就是异步非阻塞模式的。   对于这些概念,初学者的理解也许只能似是而非,我将用一个最简单的例子说明异步非阻塞Socket的基本原理和工作机制。目的是让初学者不仅对Socket异步非阻塞的概念有个非常透彻的理解,而且也给他们提供一个用Socket开发网络通信应用程序的快速入门方法。操作系统是Windows 98(或NT4.0),开发工具是Visual C++6.0。   MFC提供了一个异步类CAsyncSocket,它封装了异步、非阻塞Socket的基本功能,用它做常用的网络通信软件很方便。但它屏蔽了Socket的异步、非阻塞等概念,开发人员无需了解异步、非阻塞Socket的原理和工作机制。因此,建议初学者学习编网络通信程序时,暂且不要用MFC提供的类,而先用Winsock2 API,这样有助于对异步、非阻塞Socket编程机制的理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值