计算机网络实验报告
课程_计算机网络实验名称套接字编程试验
一、环境(详细说明运行的操作系统,网络平台,机器的IP地址)
CPU
Intel(R)Core(TM)2DuoCPUP8600
CPU主频2.40GHz双核
内存
3.00GB(DDR2667MHz)
操作系统
Windows7Ultimate
开发语言
Java
JDK版本
JDK1.6.0_26
代码编写
EclipIDEIndigoRelea
文档编写
MicrosoftWord2010
程序测试
GoogleChromeBrowr
二、实验目的
—了解应用层和运输层的作用及相关协议的工作原理和机制。
—掌握SOCKET编程的基本方法。
三、实验内容及步骤(包括主要流程和说明)
实验内容
编写一个支持多线程处理的Web服务服务端软件,要求如下:
第一级:
可配置Web服务器的IP地址、监听端口和主目录。
制作一个主页放置在主目录中,并配置Web服务器的IP地址、监听端口
和主目录。
具备完成所需功能的基本图形用户界面(GUI),并具友好性。
第二级:
选择合适的Socket编程模型,创建套接字,监听所配置的监听端口。
支持服务的启动和关闭。
具备完成所需功能的基本图形用户界面(GUI),并具友好性。
第三级:
支持多线程,能够针对每一个新的请求创建新的线程。
在服务器端的屏幕上输出每一个请求的来源(IP地址、端口号和HTTP请
求命令行)
支持一定的异常情况处理能力。
具备完成所需功能的基本图形用户界面(GUI),并具友好性。
第四级:
能够处理HTTP请求以及定位相应的HTML文件。
向客户端发送响应报文。
对于无法成功定位文件的请求,根据错误原因,作相应错误提示。
在服务器端的屏幕上能够输出对每一个请求处理的结果。
具备完成所需功能的基本图形用户界面(GUI),并具友好性
第五级:
支持多种类型文件(如TXT和JPG等)的发送。
具备简洁方便的GUI界面。
实验步骤
类的设计
本程序中设计了三个类,如下图所示:
图1类的设计
classServerCode:主线程,实现了服务器端口的侦听,服务器接受一个客
户端请求之后创建一个线程实例处理请求。
classconnectThread:子线程,从Thread类继承而来,实现了HTTP协议
的处理以及一些异常处理。
classSetting:主界面,从JFrame类继承而来,主要用来画整个界面框架
UI和处理与用户的交互。
代码编写
本程序所使用的IDE为EclipIDEIndigoRelea,将实现代码键入编辑器
中,当Eclip提示没有错误时,如下所示:
图2代码编写
即表示代码已经没有语法错误。
程序测试
点击按钮运行程序,可以看到整个配置界面,用户可以在配置界面设
置端口,IP,主文件夹,配置界面下方还有个输出面板,用来输出每个客户端
的IP,端口,以及对每个HTTP请求的处理结果,如下图所示:
图3程序界面
首先设置端口(默认8000),设置IP地址(默认本机地址127.0.0.1),设置主
目录(默认当前程序运行的目录),点击右下角应用按钮,将设置值反馈给程
序,然后点击文件——启动服务,最后打开GoogleChromeBrowr,在地址栏
输入127.0.0.1:8000/,得到如下页面:
图
然后回到主目录下,可以看到主目录下的网页文件,如下图所示:
图5目录下的
同样用GoogleChromeBrowr打开,可以看到如下页面:
图
由图4和图6可知,两个页面的内容一样,说明程序运行正常,客户端Google
ChromeBrowr从127.0.0.1地址和8000端口得到了所请求的页面。
在点击最小化之后,我们可以在任务栏看到最小化图标,
可以随时点击鼠标右键,打开程序主面板或者结束程序,
如右图所示:
四、实验结果
首先运行程序,配置按照默认设置,然后点击文件—开启服务,这时服
务器已经运行起来,打开GoogleChromeBrowr,在地址栏输入127.0.0.1:8000
/,可以得到主目录下的文件并显示在浏览器中,如图图4
所示,然后观察服务器端,我们可以看到服务器记录了每个HTTP请求命令行
以及每个HTTP请求的来源IP地址和端口,并把对每个HTTP请求的处理结
果显示在输出框中,如下图所示:
图7http请求处理
然后我们试图修改端口地址和IP地址,程序会在用户第一次试图修改IP
地址时提示用户只能输入当前已连接的网络的IPv4地址。
当用户试图在服务正在运行的情况下修改端口和IP地址或者主目录时,程
序都会给出提示,如下图所示:
图8修改ip与端口地址
然后我们点击文件—关闭服务,然后点右下角的应用按钮,在更改配置之
后,点击文件—开启服务,然后我们在GoogleChromeBrowr中输入
222.20.103.127/,得到如下页面:
图9修改ip之后的
说明程序成功地修改了端口地址和IP地址,然后更改主目录如下:
图10修改主文件目录
重新启动服务,在浏览器中输入222.20.103.127:800/可以得到如下
页面
图11修改主目录后的
打开S:UrsRooneyMC下的文件如下图所示:
图12保存在S:UrsRooneyMC的
由错误!未找到引用源。1和错误!未找到引用源。2可知,我们的程序可以
完成主目录的改变,也可以完成JPG等文件的传送。
再观察服务器端,可以看到服务器已经将所有的HTTP请求命令行和相应的处
理结果显示在输出框中。如下图所示:
图7HTTP请求响应与处理
五、实验中的问题及心得
实验中最后两个类之间的通信有些问题,不能即时将用户与服务器的交互
结果在程序中更新,比如用户改变主目录,按下应用按钮之后,应用按钮的响
应事件要涉及到一些全局参数的变更,这些全局参数在其他类中要实时的更
新。最终的解决办法是在UI类中定义一个public布尔变量,然后在其他类中
循环检测这个布尔变量的值,一旦用户的操作改变了布尔变量的值,就可以让
全局参数在其他类中得到更新。
过去只是有过Android编程的经历,还没有Socket编程的概念,通过这次
Socket编程的网络实验,让我更加清楚了计算机网络应用层的HTTP协议,以
及主机与服务器之间通信的原理,一定程度上也提高了自己的自主学习的能
力。
以往的编程语言的学习并没有多少投入到实际应用中,而是为了考试而去
背知识点,这次的实验让我对Java的编程方法有了更深入的理解。
这次实验对于我在Java和网络通信的知识的领悟又抬高了一个台阶。
附录:
(主线程)
.*;
.*;
dress;
nPane;
publicclassServerCode
{
//Mainmethod
publicstaticvoidmain(String[]args)throwsIOException
{
//Createarversocket
finalSettingstt=newSetting();
inti=0;
//Startlisteningforconnectionsontherversocket
ServerSocketrverSocket=null;
SocketconnectToClient=null;/*=();*/
try
{
while(true){
if(!g){
ssageDialog(null,"请先设置好ip和端口",
"Error",0);
continue;
}
if(!&&null!=rverSocket){
();
rverSocket=null;
();
//continue;
}
if(&&null==rverSocket){
rverSocket=newServerSocket(,-1,
ddress());
//rverSocket=newServerSocket(,-1,
ddress(byteip));
}
if(null!=rverSocket){
if(){
i=0;
=fal;
}
connectToClient=();
newconnectThread(connectToClient,i,e,
).start();
i++;
}
}
}
catch(IOExceptionex)
{
n(ex);
}
finally{
();
rverSocket=null;
();
}
}
}
(UI)
.*;
.*;
dress;
Event;
Listener;
dapter;
vent;
.*;
order;
ctory;
.*;
publicclassSettingextendsJFrame{
privateJPanelcontentPane;
publicJTextFieldport;
publicJTextFieldIpAdress;
publicJTextFieldDirectory;
privateJButtonbtnChooFolder;
publicJFileChoorFolder;
publicStringsltFile;
privateTrayIcontrayIcon;//托盘图标
privateSystemTraytray;//本操作系统托盘的实例
/*菜单*/
publicJMenuFile;
privateJMenuAbout;
publicJTextAreaoutput;
publicJButtonbtnOk;
publicJButtonbtnCancel;
publicbooleanModFlag=true;
publicbooleanStFlag=fal;
publicbooleanzero=fal;
privatebooleanFirstClicked=true;
publicintPort=8000;
publicbyte[]ip={(byte)127,(byte)0,(byte)0,(byte)1};
privateJButtonbutton;
/**
*Createtheframe.
*/
publicSetting(){
tDefaultCloOperation(_ON_CLOSE);
tResizable(fal);
tTitle("Setting");
tBounds(100,100,600,450);
JMenuBarmenuBar=newJMenuBar();
tJMenuBar(menuBar);
File=newJMenu("u6587u4EF6");
(File);
JMenuItemStartup=newJMenuItem("u542Fu52A8u670Du52A1");
ionListener(newActionListener(){
publicvoidactionPerformed(ActionEventarg0){
if(StFlag){
ssageDialog(null,"服务器已经在运行","
提示",1);
return;
}
StFlag=true;
}
});
(Startup);
JMenuItemTurnoff=newJMenuItem("u5173u95EDu670Du52A1");
ionListener(newActionListener(){
publicvoidactionPerformed(ActionEventarg0){
if(!StFlag){
ssageDialog(null,"服务器未运行","提示
",1);
return;
}
StFlag=fal;
}
});
(Turnoff);
JMenuItemquit=newJMenuItem("u9000u51FA");
ionListener(newActionListener(){
publicvoidactionPerformed(ActionEvente){
(0);
}
});
(quit);
About=newJMenu("u5173u4E8E");
Listener(newMouAdapter(){
@Override
publicvoidmouClicked(MouEventarg0){
ssageDialog(null,"基于Java的web服务器",
"About",1);
}
});
(About);
contentPane=newJPanel();
der(newEmptyBorder(5,5,5,5));
tContentPane(contentPane);
out(newFormLayout(newColumnSpec[]{
TED_GAP_COLSPEC,
("8px:grow"),
D_GAP_COLSPEC,
("max(19dlu;default):grow"),
D_GAP_COLSPEC,
("max(12dlu;default)"),
_COMPONENT_GAP_COLSPEC,
("16px"),
_COMPONENT_GAP_COLSPEC,
("62px"),
_COMPONENT_GAP_COLSPEC,
("31px:grow"),
_COMPONENT_GAP_COLSPEC,
("47px"),
_COMPONENT_GAP_COLSPEC,
("66px"),
_COMPONENT_GAP_COLSPEC,
("87px"),
_COMPONENT_GAP_COLSPEC,
("81px"),
D_GAP_COLSPEC,
("default:grow"),
_COMPONENT_GAP_COLSPEC,
("39px"),},
newRowSpec[]{
D_GAP_ROWSPEC,
("max(14dlu;default)"),
TED_GAP_ROWSPEC,
("23px"),
D_GAP_ROWSPEC,
T_ROWSPEC,
D_GAP_ROWSPEC,
T_ROWSPEC,
D_GAP_ROWSPEC,
T_ROWSPEC,
D_GAP_ROWSPEC,
T_ROWSPEC,
D_GAP_ROWSPEC,
("max(20dlu;default):grow"),
D_GAP_ROWSPEC,
T_ROWSPEC,
D_GAP_ROWSPEC,
T_ROWSPEC,
D_GAP_ROWSPEC,
("max(9dlu;default)"),
D_GAP_ROWSPEC,
("max(17dlu;default)"),
D_GAP_ROWSPEC,
("max(16dlu;default):grow"),
D_GAP_ROWSPEC,
T_ROWSPEC,
D_GAP_ROWSPEC,
T_ROWSPEC,}));
JLabellblPort=newJLabel("Port");
eground();
(lblPort,"2,8,4,1,center,center");
port=newJTextField();
(port,"8,8,3,1,fill,center");
umns(10);
t(""+Port);
JLabellabel=newJLabel("(1024-65535)");
eground();
(label,"12,8,3,1");
JLabellblIpAddress=newJLabel("IPAddress");
eground();
(lblIpAddress,"16,8,2,1,fill,center");
IpAdress=newJTextField();
Listener(newMouAdapter(){
@Override
publicvoidmouClicked(MouEventarg0){
if(FirstClicked){
ssageDialog(null,"请修改为本机的ip地址,
可在控制台中输入ipconfig得到","提示",1);
FirstClicked=fal;
}
}
});
(IpAdress,"18,8,3,1,fill,center");
umns(10);
try{
t(ddress(ip).toString().substring(1));
/*去掉前面的/*/
}catch(Exceptione){
tackTrace();
}
JLabellblMainFolder=newJLabel("MainFolder");
eground();
(lblMainFolder,"2,10,4,1,center,center");
Directory=newJTextField();
(Directory,"8,10,11,1,fill,center");
umns(10);
table(fal);
try{
sltFile=newFile(".").getCanonicalPath();
t(sltFile);
}
catch(IOExceptione){
tackTrace();
}
btnChooFolder=newJButton("Choo");
eground(A);
ionListener(newActionListener(){
publicvoidactionPerformed(ActionEvente){
if(StFlag){
ssageDialog(null,"服务器正在运行中,请
关闭服务后再修改","Error",0);
return;
}
Folder=newJFileChoor();
rentDirectory(("."));
logTitle("SelectaFolder");
eSelectionMode(ORIES_ONLY);
eptAllFileFilterUd(fal);
if(enDialog(btnChooFolder)==
E_OPTION){
sltFile=ectedFile().toString();
t(sltFile);
}
}
});
(btnChooFolder,"20,10,center,fill");
output=newJTextArea();
pStyleWord(true);
eWrap(true);
table(fal);
JScrollPanescrollPane=newJScrollPane(output);
(scrollPane,"5,14,18,11,fill,fill");
btnOk=newJButton("u5E94u7528");
ionListener(newActionListener(){
@Override
publicvoidactionPerformed(ActionEventarg0){
//TODOAuto-generatedmethodstub
if(StFlag){
ssageDialog(null,"服务器正在运行中,请
关闭服务后再修改","Error",0);
return;
}
//getthePort
try{
Port=nt(t());
if(Port<1024){
ssageDialog(null,"ThePortis
Invalid","Error",0);
All();
tFocus();
ModFlag=fal;
return;
}
}catch(NumberFormatExceptione){
tackTrace();
}
//gettheIPAddress
Stringiptp=t().trim();
if(!IsIpValid(iptp)){
ssageDialog(null,"TheIPAddressis
Invalid","Error",0);
All();
tFocus();
ModFlag=fal;
return;
}
ConvertStrToIP(ip,iptp);
ModFlag=true;
}
});
button=newJButton("u6E05u9664u8F93u51FA");
ionListener(newActionListener(){
publicvoidactionPerformed(ActionEventarg0){
t("");
if(!zero){
zero=true;
}
}
});
(button,"7,26,4,1");
(btnOk,"18,26,center,center");
/*JButton*/btnCancel=newJButton("u53D6u6D88");
ionListener(newActionListener(){
publicvoidactionPerformed(ActionEventarg0){
tVisible(fal);
}
});
(btnCancel,"20,26,center,center");
tray=temTray();//获得本操作系统托盘的实例
Toolkitkit=aultToolkit();
Imageimage=ge("");
tIconImage(image);
PopupMenupop=newPopupMenu();//构造一个右键弹出式菜单
finalMenuItemshow=newMenuItem("open");
finalMenuItemexit=newMenuItem("exit");
(show);
(exit);
trayIcon=newTrayIcon(image,"Server",pop);//实例化托盘图标
//为托盘图标监听点击事件
Listener(newMouAdapter()
{
publicvoidmouClicked(MouEvente)
{
if(ckCount()==2)//鼠标双击图标
{
//(trayIcon);//从系统的托盘实例中移除托盘图标
tExtendedState();//设置状态为正常
tVisible(true);//显示主窗体
}
}
});
//选项注册事件
ActionListeneral2=newActionListener()
{
publicvoidactionPerformed(ActionEvente)
{
//退出程序
if(rce()==exit)
{
(0);//退出程序
}
//打开程序
if(rce()==show)
{
tExtendedState();//设置状态为正常
tVisible(true);
}
}
};
ionListener(al2);
ionListener(al2);
try{
(trayIcon);//将托盘图标添加到系统的托盘实例中
}
catch(AWTExceptionex){
tackTrace();
}
tVisible(true);
}
publicbooleanIsIpValid(StringstrIp){
//判断是否是空串
if(y()){
returnfal;
}
//判断是否以数字开头
if(!t((0))){
returnfal;
}
String[]ip4=(".");
//判断是否为4块
if(!=4){
returnfal;
}
//判断每块是否都大于0且小于256
try{
for(inti=0;i<;i++){
if(nt(ip4[i])<0||
nt(ip4[i])>255){
returnfal;
}
}
}catch(NumberFormatExceptione){
tackTrace();
}
returntrue;
}
publicvoidConvertStrToIP(byte[]ip,StringstrIp){
String[]ip4=(".");
try{
for(inti=0;i<;i++){
ip[i]=(byte)nt(ip4[i]);
}
}catch(NumberFormatExceptione){
tackTrace();
}
}
}
(子线程)
dress;
;
Tokenizer;
.*;
rea;
publicclassconnectThreadextendsThread{
finalStringCRLF="rn";
privateSocketclient;
privateintcounter;
PrintStreamoutstream;
BufferedReaderinstream;
StringFolder;
JTextAreaoutput;
publicconnectThread(Socketskt,intcount,StringMainFolder,JTextArea
output){
client=skt;
counter=count;
=output;
Folder=newString(MainFolder);
try{
outstream=newPrintStream(putStream());
instream=newBufferedReader(new
InputStreamReader(utStream()));
}catch(Exceptione){
tackTrace();
}
}
publicvoidrun(){
try{
InetAddressaddr=tAddress();
StringdestIP=ng();//客户机IP地址
intdestport=t();//客户机端口号
StringhostName=onicalHostName();
("Connection"+counter+":connectedto"+destIP+"on
port"+destport+
"ClientHostName:"+hostName+"."+CRLF);
processRequest(counter);
}catch(Exceptione){
tackTrace();
}
}
privatevoidprocessRequest(intnum)throwsException{
while(true){
StringheaderLine=ne();
if(null==headerLine){
break;
}
if(("rn")||("")){
break;
}
//完成回应消息
StringServerLine="";
StringStatusLine=null;
StringContentTypeLine=null;
StringEntityBody=null;
StringContentLengthLine="error";
booleanfileExists=true;
//打开所请求的文件
FileInputStreamfis=null;
StringTokenizers=newStringTokenizer(headerLine);
Stringtemp=ken();//解析消息
if(With("POST")||
With("HEAD")){
StatusLine="HTTP/1.0501NotImplemented"+CRLF;
ContentTypeLine="text/html";
EntityBody=""+"
Implemented"+
"
501NotImplemented"+"+CRLF";(es());
(es());
(es());
(es());
(es());
(es());
("STATUSrequest"+num+":"+"therequest
notimplemented!"+CRLF);
}
if(With("GET")){
if(("GET")){
("request"+num+":"+headerLine+CRLF);
StringfileName=ken();
if(!th("")){
Folder+="";
}
Stringfilename1=Folder+ing(1);
try{
fis=newFileInputStream(filename1);//文件输出流
}catch(Exceptione){
fileExists=fal;
("STATUSrequest"+num+":"+"file
notfound-->:"+filename1+CRLF);
}
if(fileExists){
StatusLine="HTTP/1.0200OK"+CRLF;
ContentTypeLine="Content-Type:"+
contentType(filename1)+CRLF;
ContentLengthLine="Content-Length:"+(new
Integer(ble())).toString()+CRLF;
}
el{
StatusLine="HTTP/1.0404NotFound"+CRLF;
ContentTypeLine="text/html";
EntityBody=""+"
Found"+
"
404NotFound"+fileName+".html+CRLF";
}
//发送到服务器信息
(es());
(es());
(es());
(es());
(es());
if(fileExists){
ndBytes(fis,outstream);
();
("STATUSrequest"+num+":"+
"Succeed!"+CRLF);
}
el{
(es());
}
}
el{
StatusLine="HTTP/1.0400BadRequest"+CRLF;
ContentTypeLine="text/html";
EntityBody=""+"
Request"+
"
400BadRequest"+"+CRLF";(es());
(es());
(es());
(es());
(es());
(es());
("STATUSrequest"+num+":"+"therequest
isinvalid!"+CRLF);
}
}
}
try{
();
();
}catch(Exceptione){
tackTrace();
}
finally{
();
}
}
privatestaticvoidndBytes(FileInputStreamfis,OutputStreamos)
throwsException{
//创建一个1Kbuffer
byte[]buffer=newbyte[1024];
intbytes=0;
//将文件输出到套接字流中
while((bytes=(buffer))!=-1){
(buffer,0,bytes);
}
}
privatestaticStringcontentType(StringfileName){
if(th(".htm")||th(".html")){
return"text/html";
}
return"fileName";
}
}
本文发布于:2022-12-02 17:40:28,感谢您对本站的认可!
本文链接:http://www.wtabcd.cn/fanwen/fan/88/39283.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |