实验四 基于Socket的CS程序开发.docx
《实验四 基于Socket的CS程序开发.docx》由会员分享,可在线阅读,更多相关《实验四 基于Socket的CS程序开发.docx(11页珍藏版)》请在冰豆网上搜索。
实验四基于Socket的CS程序开发
实验四基于Socket的CS程序开发
淮海工学院计算机工程学院
实验报告书
课程名:
计算机网络
题目:
基于Socket的C/S程序开发
班级:
G计121
学号:
2012150232
姓名:
成燕
一.实验目的与要求
理解和巩固传输层与套接字的基本知识,掌握利用套接字实现面向连接的数据传输的一般方法,深入理解客户/服务器工作模式,学会简单的客户/服务器程序的开发。
二.实验内容或题目
利用Java语言提供的Socket技术,建立一个C/S模式的应用,允许客户端用户输入2个整数,服务器端接收这2个整数,并计算出它们的和、差、积、商,最后送回客户端
三.实验步骤与源程序
1、客户端源代码如下:
import.*;
importjava.io.*;
importjava.awt.*;
importjava.awt.event.*;
importjavax.swing.*;
publicclassClientextendsFrameimplementsRunnable,ActionListener
{DataInputStreamin=null;
DataOutputStreamout=null;
Panelp;
Labellab1,lab2,lab3;
TextFieldtf1,tf2,tf3;
Buttonconnection,send;
Socketsocket=null;
Threadthread;
TextAreatext;
publicClient()
{super("客户端:
");
setLayout(newFlowLayout());
setSize(300,250);//设置窗口大小
setLocation(200,200);//设置窗口显示位置
setResizable(false);
p=newPanel();
p.setLayout(null);p.setBounds(0,0,300,250);
addWindowListener(newWindowAdapter()
{
publicvoidwindowClosing(WindowEvente)
{System.exit(0);}
});
text=newTextArea();
lab1=newLabel("输入IP地址:
");lab1.setBounds(5,5,60,25);
lab2=newLabel("第一个数字:
");lab2.setBounds(5,35,60,25);
lab3=newLabel("第二个数字:
");lab3.setBounds(5,65,60,25);
tf1=newTextField(10);tf1.setBounds(80,5,100,25);
tf2=newTextField(10);tf2.setBounds(80,35,100,25);
tf3=newTextField(10);tf3.setBounds(80,65,100,25);
connection=newButton("连接服务器");
connection.setBounds(200,5,90,25);
connection.addActionListener(this);
send=newButton("发送数据");
send.setBounds(200,65,90,25);
send.addActionListener(this);
text=newTextArea(200,50);
text.setBounds(5,100,290,110);
p.add(lab1);p.add(lab2);p.add(lab3);
p.add(tf1);p.add(tf2);p.add(tf3);
p.add(connection);p.add(send);
p.add(text);add(p);
setVisible(true);
socket=newSocket();
thread=newThread(this);
}
publicvoidactionPerformed(ActionEvente)
{if(e.getSource()==connection)
{
InetAddressaddress=null;
InetSocketAddresssocketAddress=null;
try//请求和服务器建立套接字连接:
{
if(socket.isConnected()){}
else
{address=InetAddress.getByName(tf1.getText());
socketAddress=newInetSocketAddress(address,8755);
socket.connect(socketAddress,2000);//*等待2秒中
in=newDataInputStream(socket.getInputStream());
out=newDataOutputStream(socket.getOutputStream());
send.setEnabled(true);
JOptionPane.showMessageDialog(this,"连接成功!
",
"成功!
",JOptionPane.INFORMATION_MESSAGE);
thread.start();
}
}
catch(IOExceptionex)
{System.out.println("timeout"+ex);
System.out.println(socketAddress.getHostName()+":
"+socketAddress.getPort());
JOptionPane.showMessageDialog(this,"连接超时!
","错误!
",JOptionPane.ERROR_MESSAGE);
newClient();
dispose();
}
}
if(e.getSource()==send)
{Strings=tf2.getText()+","+tf3.getText();
if(s!
=null)
{try
{out.writeUTF(s);
}
catch(IOExceptione1){}
}
}
}
publicvoidrun()
{Strings=null;
while(true)
{
try
{s=in.readUTF();
text.append(s+"\n");
}
catch(IOExceptione)
{text.append("与服务器已断开");break;
}
}
}
publicstaticvoidmain(Stringargs[])
{newClient();
}
}
2、服务器端源代码如下:
import.*;
importjava.util.*;
importjava.io.*;
importjava.awt.*;
importjava.awt.event.*;
importjavax.swing.*;
publicclassServer
{
publicServer()
{ServerSocketserver=null;
Server_threadthread;
Socketyou=null;
while(true)
{
try
{server=newServerSocket(8755);
}
catch(IOExceptione1)
{System.out.println("正在监听");//ServerSocket对象不能重复创建
}
try
{System.out.println("等待客户呼叫");
you=server.accept();
System.out.println("已连接到客户");
System.out.println("客户的地址:
"+you.getInetAddress());
}
catch(IOExceptione)
{System.out.println("正在等待客户");}
if(you!
=null)
{newServer_thread(you).start();//为每个客户启动一个专门的线程
}
}
}
publicstaticvoidmain(Stringargs[])
{newServer();
}
}
classServer_threadextendsThread
{
Socketsocket;
DataOutputStreamout=null;
DataInputStreamin=null;
Strings=null;
booleanquesion=false;
Server_thread(Sockett)
{socket=t;
try
{out=newDataOutputStream(socket.getOutputStream());
in=newDataInputStream(socket.getInputStream());
}
catch(IOExceptione){}
}
publicvoidrun()
{
while(true)
{doublea[]=newdouble[2];inti=0;
try
{
s=in.readUTF();//堵塞状态,除非读取到信息
quesion=false;
StringTokenizerfenxi=newStringTokenizer(s,",");
while(fenxi.hasMoreTokens()&&quesion==false)
{
Stringtemp=fenxi.nextToken();
try
{a[i]=Double.valueOf(temp).doubleValue();i++;
}
catch(NumberFormatExceptione)
{out.writeUTF("请输入数字字符");
quesion=true;
}
}
if(quesion==false)
{
doubles=a[0]+a[1];
doublep=a[0]-a[1];
doubleq=a[0]*a[1];
doubler=a[0]/a[1];
out.writeUTF(""+a[0]+"+"+a[1]+"="+s);
out.writeUTF(""+a[0]+"-"+a[1]+"="+p);
out.writeUTF(""+a[0]+"*"+a[1]+"="+q);
out.writeUTF(""+a[0]+"/"+a[1]+"="+r);
System.out.println("客服端数据:
"+a[0]+"和"+a[1]);
System.out.println("完成客户端运算");
}
}
catch(IOExceptione)
{
System.out.println("客户离开");return;
}
}
}
}
四.测试数据与实验结果
客户机建立连接:
服务器收到连接:
客户端向服务器发送数据并进行运算:
服务器收到数据:
五.结果分析与实验体会
本次实验利用Java语言提供的Socket技术,我根据java课本完成实验所需要的程序,成功实现相应的功能。
通过本次实验,我理解和巩固传输层与套接字的基本知识,掌握利用套接字实现面向连接的数据传输的一般方法,深入理解客户/服务器工作模式,学会简单的客户/服务器程序的开发。
以前对套接字不是很熟悉,经过这次实验,明白了套接字在网络编程中有着重要的角色,比如我们的聊天工具和计算器等等。
希望这次的实验内容在以后的实例中能够运用的得心应手。
六.思考题
1.Java语言中,服务器端和客户端套接字对象类相同吗?
如不同,有何差别?
答:
不相同。
客户端的程序使用Socket类建立到服务器的套接字连接,而服务器使用ServerSocket对象等待接收客户的信息。
2.程序编写完毕并编译后,先运行客户端程序,还是先运行服务器端程序?
为什么?
答:
先运行服务器端,如果服务器端不运行或后运行,客户端运行后无法与服务器端建立连接,就不能用到服务器端的服务。
3.Java语言中如何使用UDP协议进行数据传输的?
答:
Java里UDP协议传送的方式细节已经封装了到类DatagramSocket里,只要用DatagramSocket的对象进行传输数据就可以了,底层实现是应该依靠本地C语言程序来完成的。