互联网实践及应用报告

更新时间:2024-06-26 05:01:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

互联网技术及应用实践

实验报告

报告名称: 路由器配置及应用

路由追踪的实现 EMAIL的客户端程序 开发一个简单的WEB服务器

学生姓名:

学 号: 指导教师:

实验一 路由器配置及应用

1.实验原理

2.实验步骤

第一步:在路由器Router1上配置快速以太网口的IP地址

Router1#configure terminal

Router1(config)#interface FastEthernet 0/0 ! 进入以太网0口配置状态

或Router1(config)#interface FastEthernet 1/0

Router1(config-if)#ip address 172.16.1.1 255.255.255.0 ! 为以太网0口配置地址

Router1(config-if)#no shutdown ! 打开以太网0口 Router1(config-if)#end

第二步:在路由器Router1上配置广域网口的IP地址和时钟频率(假设Router1为DCE端)

Router1#con

Router1(config)#interface serial 2/0 ! 进入广域网0口配置状态 或Router1(config)#interface serial 1/2

Router1(config-if)#ip address 172.16.2.1 255.255.255.0 ! 为广域网0口配置地址

Router1(config-if)#clock rate 64000 ! DCE端需设置端口时钟频率 Router1(config-if)#no shutdown ! 打开广域网0口 Router1(config-if)#end

验证测试:验证路由器接口配置状态。

Router1#show ip interface brief ! 显示IP端口状态简况 Interface IP-Address OK? Method Status Protocol FastEthernet0/0 172.16.1.1/24 YES manual up up

FastEthernet0/1 no address YES unset administratively down down Serial2/0 172.16.2.1/24 YES manual up up

Serial3/0 no address YES unset administratively down down Null 0 no address YES up 第三步:为Router1添加静态路由

Router1#con

Router1(config)#ip route 172.16.3.0 255.255.255.0 172.16.2.2 ! 添加静态路由

Router1(config)#end

Router1#show ip route ! 显示路由表

Codes: C - connected, S - static, R - RIP O - OSPF, IA - OSPF inter area

E1 - OSPF external type 1, E2 - OSPF external type 2 Gateway of last resort is not set 172.16.0.0/24 is subnetted, 3 subnets

C 172.16.1.0 is directly connected, FastEthernet0 C 172.16.2.0 is directly connected, Serial0 S 172.16.3.0 [1/0] via 172.16.2.2 Router1#wr !保存所作的修改

第四步:在路由器Router2(R2624)上配置快速以太网口的IP地址

Router2#con

Router2(config)#interface fastethernet 0/0 或Router2(config)#interface fastethernet 1/0

Router2(config-if)#ip address 172.16.3.2 255.255.255.0 Router2(config-if)#no shutdown Router2(config-if)#end

第五步:在路由器Router2(R2624)上配置广域网口的IP地址

Router2#conf

Router2(config)#interface serial 2/0 或Router2(config)#interface serial 1/2

Router2(config-if)#ip address 172.16.2.2 255.255.255.0 Router2(config-if)#no shutdown Router2(config-if)#end

Router2#show ip interface brief

Interface IP-Address OK? Method Status Protocol FastEthernet0/0 172.16.3.2 YES manual up up

FastEthernet0/1 unassigned YES unset administratively down down Serial2/0 172.16.2.2 YES manual up up

Serial3/0 unassigned YES unset administratively down down 图下图:

图1.1

第六步:测试两台路由器之间的连通性

Router2#ping 172.16.2.1

Type escape sequence to abort.

Sending 5, 100-byte ICMP Echoes to 172.16.2.1, timeout is 2 seconds:

!!!!!

Success rate is 100 percent (5/5), round-trip min/avg/max = 1/1/4 ms

如下图:

图1.2

第七步:为Router2(R2624)添加静态路由

Router2#con

Configuring from terminal, memory, or network [terminal]? Enter configuration commands, one per line. End with CNTL/Z. Router2(config)#ip route 172.16.1.0 255.255.255.0 172.16.2.1 Router2(config)#end Router2#show ip route

Codes: C - connected, S - static, R - RIP O - OSPF, IA - OSPF inter area

E1 - OSPF external type 1, E2 - OSPF external type 2 Gateway of last resort is not set 172.16.0.0/24 is subnetted, 3 subnets S 172.16.1.0 [1/0] via 172.16.2.1

C 172.16.2.0 is directly connected, Serial0

C 172.16.3.0 is directly connected, FastEthernet0 Router2#wr 如下图:

图1.3

第八步:用ping命令对PC1,PC2进行连通性检测 如下图:

图1.4

注意事项:

(1)如果两台路由器经过串口直接相连,则必须在时钟一端设置时钟频率(DCE)。

(2)PC机必须配置默认网关。

实验二 路由追踪

1. 实验目的:

熟悉掌握路由器实现路由追踪,熟悉ICMP协议 2. 实验环境:

Microsoft Visual C++6.0 3.实验原理:

路由追踪是从源主机向目的主机发送一连串的IP数据报,数据包中封装的是无法交付的UDP数据报。源主机先向目的主机发送一个回应请求报文(类型8),TTL设置为1,第一个路由器收到后 将TTL设为1第一个路由器收到后将TTL减1,这样TTL变为0,分组被废除,同时路由器向源主机发送一个TTL超时报文(类型为11),报文的IP报头中的源IP地址就是第一个路由器的地址,源主机可以通过对该报文进行分析,得到第一个路由器的地址,接着发送TTL等于2的报文得到第二个路由器的地址,再发送TTL等于3的报文,如此下去直到收到目的主机的回应应答报文(类型为0)或不可到达报文(类型为3),或者到了最大跳数(要检测路由器个数的最大值)。这样,源主机达到了自己的目的,因为这些路由器和最后的目的主机发送的ICMP报文正好给源主机想知道的路由信息——到达目的主机所经过的路由器的IP地址,以及到达其中每一个路由器的往返时间。 4.源代码如下:

#define WIN32_LEAN_AND_MEAN

#include //使用原始套接字需要WinSock2的支持

#include //进行IPPROTO_IP级别设置时用到

#include #include

#define ICMP_ECHO 8 //发送Ping请求时的ICMP报文类型

#define ICMP_ECHOREPLY 0 //接收Ping回复时的ICMP报文类型

#define ICMP_TIMEOUT 11 //ICMP超时报文类型 #define ICMP_MIN 8 //Minimum 8-byte ICMP packet (header)

#define MAX_PACKET 1024 //Max ICMP packet size

#define DEICMP_PACKSIZE 44 //Defaut ICMP PACKET SIZE

char lpdest[16]; //用来存放目的IP地址

DWORD cStartTickCount; //用来存放发送包的起始时间

#pragma comment( lib, \

typedef struct _icmphdr //ICMP头部定义,被封装在IP包中

{

BYTE i_type; //报文类型 BYTE i_code; //代码 USHORT i_cksum; //校验和 USHORT i_id; //标识符 USHORT i_seq; //序号 }IcmpHeader;

//初始化ICMP头部

void FillICMPData(char *icmp_data,int datasize) {

IcmpHeader *icmp_hdr=NULL; char *datapart=NULL;

icmp_hdr=(IcmpHeader *)icmp_data;

icmp_hdr->i_type=ICMP_ECHO; //request an ICMP echo icmp_hdr->i_code=0;

icmp_hdr->i_id=(USHORT)GetCurrentProcessId(); icmp_hdr->i_cksum=0; icmp_hdr->i_seq=0;

datapart=icmp_data+sizeof(IcmpHeader);

memset(datapart,'E',datasize-sizeof(IcmpHeader)); }

//校验和函数

USHORT checksum(USHORT *buffer,int size) {

unsigned long cksum=0; while(size>1) {

cksum+=*buffer++; size-=sizeof(USHORT); }

if(size)

cksum+=*(UCHAR *)buffer;

cksum=(cksum>>16)+(cksum & 0xffff); cksum+=(cksum>>16);

return (USHORT)(~cksum);; }

int DecodeIPHeader(char *buf,int bytes,struct sockaddr_in *from)

{

IcmpHeader *icmphdr=NULL; DWORD tick;

static int icmpcount=1; unsigned short iphdrlen; //判断接收操作是否超时 if(!buf) {

printf(\timed out.\\n\

return 1; }

tick=GetTickCount();

iphdrlen=(buf[0] & 0x0f)*4;

icmphdr=(IcmpHeader *)(buf+iphdrlen); if(bytes

printf(\few bytes from %s\\n\>sin_addr));

return 0; }

//判断接收的ICMP报文是否为超时报文

if(icmphdr->i_type==ICMP_TIMEOUT&&icmphdr->i_code==0) {

printf(\ %-15s Mms\\n\cStartTickCount); return 0; }

//判断接收的ICMP报文是否为回复报文 else if(icmphdr->i_type==ICMP_ECHOREPLY&&icmphdr->i_id==GetCurrentProcessId()) {

printf(\ %-15s Mms\\n\cStartTickCount);

printf(\ return 1; }

//其他类型,表示不可达 else {

printf(\ Destination host is unreachable!\\n\

return 1;

} }

int main() {

WSADATA wsaData;

SOCKET sockRaw=INVALID_SOCKET; struct sockaddr_in dest, from;

int

i,bread,fromlen=sizeof(from),timeout=1000,ret;

struct hostent *hp=NULL;

char *icmp_data=NULL,*recvbuf=NULL; USHORT seq_no=0;

printf(\ scanf(\

if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0) {

printf(\ return -1; }

//创建套接字

sockRaw=WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL,0,WSA_FLAG_OVERLAPPED);

if(sockRaw==INVALID_SOCKET) {

printf(\ return -1; }

//对锁定套接字设置超时

bread=setsockopt(sockRaw,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout,sizeof(timeout));

if(bread==SOCKET_ERROR) {

printf(\failed:%d\\n\

return -1; }

timeout=1000;

bread=setsockopt(sockRaw,SOL_SOCKET,SO_SNDTIMEO,(char *)&timeout,sizeof(timeout));

if(bread==SOCKET_ERROR)

{

printf(\failed:%d\\n\

return -1; }

//解析目标地址,将主机名转化为IP地址 memset(&dest,0,sizeof(dest)); dest.sin_family=AF_INET;

if((dest.sin_addr.S_un.S_addr=inet_addr(lpdest))==INADDR_NONE)

{

if((hp=gethostbyname(lpdest))!=NULL) {

memcpy(&(dest.sin_addr.S_un.S_addr),hp->h_addr_list[0],hp->h_length);

dest.sin_family=hp->h_addrtype;

printf(\

} else {

printf(\failed:%d\\n\

return -1; } }

//Create the ICMP pakcet icmp_data=

(char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,MAX_PACKET);

recvbuf = (char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,MAX_PACKET);

if(!icmp_data) {

printf(\ return -1; }

memset(icmp_data,0,MAX_PACKET);

FillICMPData(icmp_data,DEICMP_PACKSIZE);

printf(\ IP Address Time elapsed\\n\

//开始发送/接收ICMP报文 for(i=1;i<=255;i++) {

int bwrote;

//设置IP包的生存期

ret=setsockopt(sockRaw,IPPROTO_IP,IP_TTL,(char *)&i,sizeof(int));

if(ret==SOCKET_ERROR) {

printf(\failed:%d\\n\

}

((IcmpHeader *)icmp_data)->i_cksum =0; ((IcmpHeader *)icmp_data)->i_seq=seq_no++; //Sequence number of ICMP packets

((IcmpHeader *)icmp_data)->i_cksum=checksum((USHORT *)icmp_data,DEICMP_PACKSIZE);

//发送ICMP包请求查询

cStartTickCount=GetTickCount();

bwrote=sendto(sockRaw,icmp_data,DEICMP_PACKSIZE,0,(struct sockaddr *)&dest,sizeof(dest));

if(bwrote==SOCKET_ERROR) {

if(WSAGetLastError()==WSAETIMEDOUT) {

printf(\ continue; }

printf(\ return -1; }

if(bwrote

printf(\ }

//接收ICMP回复包

bread=recvfrom(sockRaw,recvbuf,MAX_PACKET,0,(struct sockaddr *)&from,&fromlen);

if(bread==SOCKET_ERROR) {

if(WSAGetLastError()==WSAETIMEDOUT) {

DecodeIPHeader(NULL,0,NULL); continue; }

printf(\failed:%d\\n\

return -1; }

if(DecodeIPHeader(recvbuf,bread,&from)) break; Sleep(1000); }

system(\

if(sockRaw!=INVALID_SOCKET) closesocket(sockRaw);

HeapFree(GetProcessHeap(),0,recvbuf); HeapFree(GetProcessHeap(),0,icmp_data); WSACleanup();

return 0;

}

5.实验结果如图:

实验三 EMAIL的客户端程序

1.代码如下:

using System;

using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows;

using System.Windows.Controls; using System.Windows.Data;

using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media;

using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.Net.Mail; using System.Net.Sockets; using System.IO;

namespace mail {

///

/// MainWindow.xaml 的交互逻辑 ///

public partial class MainWindow : Window {

TcpClient server;//接服务器

string sendstring;//用于存储POP3服务命令参数

byte[] bufferstring;//用于存储POP3服务命令参数字节数 NetworkStream networkstream;//接服务器与服务器进行数据交互

StreamReader streamreader;//读取信息数据

public MainWindow() {

InitializeComponent(); }

private void sendMail_Click(object sender, RoutedEventArgs e)

{

//SmtpClient client = new SmtpClient(\

SmtpClient client = new SmtpClient(\

client.Port = 25;

MailMessage mail = new MailMessage();

mail.From = new MailAddress(\我是1234\加上自定义的发件人显示名称

mail.To.Add(new MailAddress(\ mail.Subject = \

mail.Body = \ client.DeliveryMethod = SmtpDeliveryMethod.Network;

client.UseDefaultCredentials = true; //启用身份认证

mail.Priority = MailPriority.Normal; //邮件优先级

//mail.Attachments.Add(new Attachment(@\我的文档\\消息.txt\附件

//mail.Body = new System.IO.StreamReader(@\我的文档\\ttt.txt\从文本文件中读取邮件内容

mail.BodyEncoding = System.Text.Encoding.UTF8;

client.Credentials = new System.Net.NetworkCredential(\

\如果是匿名发送则不需要这一句(这里将账号和密码用x和*代替了)

// client.Send(mail); client.SendCompleted += new SendCompletedEventHandler(SendCompletedCallback);//回调函数

string userState = \测试\

client.SendAsync(mail, userState);

}

private static void SendCompletedCallback(object sender, System.ComponentModel.AsyncCompletedEventArgs e)

{

if (e.Cancelled) //邮件发送被取消 {

}

if (e.Error != null) //邮件发送失败 {

}

else //发送成功 {

} }

private void Showinfo() {

richTextBox1.Document.Blocks.Clear(); try {

string strResult = \

sendstring = \\+ this.textBox4.Text + \存储从服务器获得一条信息的命令

bufferstring = Encoding.ASCII.GetBytes(sendstring.ToCharArray());

networkstream.Write(bufferstring, 0, bufferstring.Length);

strResult = streamreader.ReadLine(); if (strResult[0] != '-') {

//不断地读取邮件内容,只到结束标志:英文句号

while (strResult != \ {

this.richTextBox1.AppendText(strResult + \

strResult = streamreader.ReadLine(); } } else {

this.richTextBox1.AppendText(\邮件错误\

} }

catch (Exception ey)

{

MessageBox.Show(ey.Message); } }

private void getMail_Click(object sender, RoutedEventArgs e)

{

Showinfo(); }

private void login_Click(object sender, RoutedEventArgs e)

{

server = new TcpClient(this.textBox1.Text, 110);//实例TcpClient 类对象联接服务器

networkstream = server.GetStream();//实例NetworkStream类对象接收返回发送的数据

streamreader = new StreamReader(networkstream);//实例StreamReader类对象读取数据

try {

sendstring = \\+ this.textBox2.Text + \存储用户名

bufferstring = Encoding.GetEncoding(\

networkstream.Write(bufferstring, 0, bufferstring.Length);//将用户名发送到服务器

richTextBox1.AppendText(streamreader.ReadLine() + \将用用户显示在 richTextBox控件中

sendstring = \\+ this.textBox3.Text + \存储用户密码

bufferstring = Encoding.GetEncoding(\

networkstream.Write(bufferstring, 0, bufferstring.Length);//将用户密码发送到服务器

richTextBox1.AppendText(streamreader.ReadLine() + \

sendstring = \储存从服务器获得所有信息序号和字节数命令

bufferstring =

Encoding.GetEncoding(\

networkstream.Write(bufferstring, 0, bufferstring.Length);//从服务器获得所有信息序号和字节数

string strResult = streamreader.ReadLine();//读取从服务器返回的数据

if (strResult.IndexOf('-') == -1) {

richTextBox1.AppendText(strResult + \

sendstring = \存储从服务器中获得信息列表和大小的命令

bufferstring = Encoding.GetEncoding(\

networkstream.Write(bufferstring, 0, bufferstring.Length);

string strInfo = streamreader.ReadLine(); string[] str = strInfo.Split(' ');

richTextBox1.AppendText(\邮件数量:\+ str[1] + \

richTextBox1.AppendText(str[1] + \封邮件总容量为\

MessageBox.Show(this.textBox2.Text + \用户您好!!!\

} else {

MessageBox.Show(\读取信息有误,请重新登录\

}

}

catch (Exception ey) {

MessageBox.Show(ey.Message); } } } }

2.实验结果:

实验四 简单的WEB服务器开发

1. 实验目的

了解web服务器的实现原理,并编程实现一个简单的web服务器。 2.开发环境

Windows xp操作系统 Java语言编程 3.实验原理

WWW是以Internet作为传输媒介的一个应用系统,WWW网上最基本的传输单位是Web网页。WWW的工作基于客户机/服务器计算模型,由Web 浏览器(客户机)和Web服务器(服务器)构成,两者之间采用超文本传送协议(HTTP)进行通信。HTTP协议是基于TCP/IP协议之上的协议,是Web浏览器和Web服务器之间的应用层协议,是通用的、无状态的、面向对象的协议。HTTP协议的作用原理包括四个步骤:连接,请求,应答,关闭应答。

根据上述HTTP协议的作用原理,实现GET请求的Web服务器程序的方法如下:

(1) 创建ServerSocket类对象,监听端口8080。这是为了区别于HTTP的标准TCP/IP端口80而取的;

(2) 等待、接受客户机连接到端口8080,得到与客户机连接的socket; (3) 创建与socket字相关联的输入流instream和输出流outstream; (4) 从与socket关联的输入流instream中读取一行客户机提交的请求信息,请求信息的格式为:GET 路径/文件名 HTTP/1.0

(5) 从请求信息中获取请求类型。如果请求类型是GET,则从请求信息中获取所访问的HTML文件名。没有HTML文件名时,则以index.html作为文件名;

(6) 如果HTML文件存在,则打开HTML文件,把HTTP头信息和HTML文件内容通过socket传回给Web浏览器,然后关闭文件。否则发送错误信息给Web浏览器;

(7) 关闭与相应Web浏览器连接的socket字。

可以总结出Web服务器的设计流程并作出其设计流程图,如图4-1所示。

图4-1 Web服务器的程序设计流程

4.主要代码如下

在Java工程中建立包webserver和类HttpServer、Request、Response,在对应框中输入以下程序代码:

-------------------------HttpServer.java-------------------------------

package webserver; import java.io.File;

import java.io.FileInputStream; import java.io.FileOutputStream; import java.util.Properties; import java.io.IOException; import java.util.Enumeration; import java.net.ServerSocket; import java.net.Socket; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintStream;

public class HttpServer {

private int iPort = 8080; //default port

public static String Basic_Root=System.getProperty(\ public static String WEB_ROOT = System.getProperty(\ File.separator + \ public static int count=0; public HttpServer() {

System.out.println(\欢迎使用Web服务器,本服务器只支持静态网页。\

System.out.println(\检查配置文件及网页文件夹...\ getConfig(); start(); }

public static void main(String[] args) {

HttpServer httpserver = new HttpServer(); }

private void getConfig() {

File fileCon=new File(Basic_Root,\ File fileDir=new File(WEB_ROOT);

File fileWeb=new File(WEB_ROOT,\ if(!fileCon.exists()) {

System.out.println(\配置文件Config.ini损坏,重建中...\ reBuildConfig(fileCon);

}

if (!fileDir.exists()) {

System.out.println(\网页存放文件夹不存在,重建中...\ fileDir.mkdir();

System.out.print(\完成!请在\

System.out.println(WEB_ROOT+\中放置网页文件...\ System.out.println(\服务器将重新初始化...\ getConfig(); }

if (!fileWeb.exists()) {

reBuildWeb(fileWeb); }

Properties pps = new Properties(); try {

pps.load(new FileInputStream(\ Enumeration enumer = pps.propertyNames(); String strKey = (String) enumer.nextElement(); String strValue = pps.getProperty(strKey); if (strValue.equals(\ {

WEB_ROOT = strValue; }

System.out.println(\网页文件的存放路径为: \ strKey = (String) enumer.nextElement();

strValue = pps.getProperty(strKey); if (strValue.equals(\ {

iPort = Integer.parseInt(strValue); }

System.out.println(\服务器访问端口为:\ System.out.println(\您可以修改Config.ini文件重新设定以上配置\

System.out.println(\启动检查完成,服务器初始化中...\ }

catch (IOException ex) {

ex.printStackTrace(); } }

public void start() {

System.out.println(\服务器启动中...\ ServerSocket serverSocket; try {

serverSocket = new ServerSocket(iPort); System.out.println(\启动完成!\ System.out.println(\您现在可以在浏览器中访问http://localhost:8080/,以测试服务器是否运行\ while (true) {

Socket socket = null;

InputStream input = null; OutputStream output = null; System.out.println(\等待连接...\ socket = serverSocket.accept();

System.out.println(socket.getInetAddress().toString()+\请求连接\ input=socket.getInputStream(); output=socket.getOutputStream();

System.out.println(\服务器开始处理第\次连接\

//开始处理并分析请求信息

Request request=new Request(input); request.parse(); //开始发送请求资源

Response response=new Response(output); response.setRequest(request); response.sendStaticResource(); //关系连接 socket.close();

System.out.println(\连接已关闭!\ } }

catch(Exception ex) {

ex.printStackTrace(); System.out.println(\ //continue; }

}

private void reBuildConfig(File file) { try {

file.createNewFile();

FileOutputStream fos=new FileOutputStream(file); PrintStream sp=new PrintStream(fos); sp.println(\ sp.println(\ sp.close();

System.out.println(\配置文件Config.ini创建成功,您可以修改WEB_ROOT的值改变网页文件的存放路径,修改PORT的值改变访问端口!\ }

catch (IOException ex) {

ex.printStackTrace();

System.out.println(\重建配置文件Config.ini失败\ System.out.println(\服务器将使用默认配置...\ } }

private void reBuildWeb(File file) { try {

file.createNewFile();

FileOutputStream fos=new FileOutputStream(file); PrintStream sp=new PrintStream(fos);

sp.println(\ sp.println(\

sp.println(\简单Web服务器\ sp.println(\ sp.println(\

sp.println(\服务器已经成功运行 \

sp.println(\ sp.println(\ sp.close(); }

catch (Exception ex) {

ex.printStackTrace(); } } }

-----------------------Request.java------------------------------------

package webserver;

import java.io.InputStream; public class Request {

public Request() { }

private InputStream input; private String uri;

public Request(InputStream input) {

this.input = input; }

public void parse()//取得请求信息 {

StringBuffer request = new StringBuffer(2048); int i;

byte[] buffer = new byte[2048]; try {

i = input.read(buffer); }

catch (Exception ex) {

ex.printStackTrace(); i = -1; }

for (int j = 0; j < i; j++) {

request.append((char) buffer[j]); }

System.out.println(request.toString()); uri = parseUri(request.toString());

System.out.println(\用户请求:\ }

private String parseUri(String requestString)//分析请求信息,并返回 {

int index1, index2;

index1 = requestString.indexOf(\ if (index1 != -1) {

index2 = requestString.indexOf(\ if (index2 > index1) {

return requestString.substring(index1 + 1, index2); } }

return null; }

public String getUri() {

if (uri.compareTo(\ {

uri=\ }

if (uri.indexOf(\ {

uri+=\ }

return uri; } }

----------------------------Response.java------------------------------

package webserver;

import java.io.OutputStream; import java.io.IOException; import java.io.FileInputStream; import java.io.File; public class Response {

private static final int BUFFER_SIZE = 1024; Request request; OutputStream output;

public Response(OutputStream output) {

this.output = output; }

public void setRequest(Request request) {

this.request = request; }

public void sendStaticResource()//发送请求资源 throws IOException {

byte[] bytes = new byte[BUFFER_SIZE]; FileInputStream fis = null; try {

File file = new File(HttpServer.WEB_ROOT, request.getUri());

if (file.exists()) {

System.out.println(\开始发送用户请求资源...\ fis = new FileInputStream(file);

int ch = fis.read(bytes, 0, BUFFER_SIZE); while (ch != -1) {

output.write(bytes, 0, ch);

ch = fis.read(bytes, 0, BUFFER_SIZE); }

System.out.println(\发送完毕!\ } else {

System.out.println(\用户请求的资源不存在\ String errorMessage = \Found\\r\\n\

\ \

\ output.write(errorMessage.getBytes()); } }

catch (Exception ex) {

ex.printStackTrace();

System.out.println(\获取请求资源错误,请检查本地资源设置!\

System.exit(1); }

if (fis != null) {

fis.close(); } } }

5.程序运行结果如下

为了确保上述程序的正确性,进行调试运行,在工程文件的webroot中建立html文件,在index.html文件中输入“服务器已经成功运行”如下图4.1所示。

图4.1在index.html文件中如图字样

右击运行HttpServer服务器结果显示为如图4.2所示:

图4.2 运行应用程序的结果

应用程序窗口显示,等待连接,/127.0.0.1请求连接,服务器处理连接,用户请求:/index.html,开始发送用户请求资源,发送完毕,连接关闭。内容如图4.3所示:

图4.3运行应用程序后结果

本文来源:https://www.bwwdw.com/article/8ww3.html

Top