- 实验内容:
- 利用Java或C++语言,分别基于TCP和UDP编写一个简单的Client/Server网络应用程序。要求实现客户向服务器传输任意一个字符串,服务器将收到的字符串变换成大写后传回客户。
- 修改上述程序,实现服务器根据客户请求,将服务器端指定的文件可靠地传输给客户。如果服务器没有指定的文件,服务器将给客户返回一个信息,通知客户其请求文件不存在。
- 有条件的同学可以进一步改进b)的程序,使之更实用。比如可以请求服务器先传输目录,然后客户根据目录请求传输文件等。
- 实验方式:每位同学上机编程实验,实验指导教师现场指导。程序可参考附录的程序1、程序2、程序3和程序4(程序中有错误需完善)
- 实验报告:在实验报告中要说明Socket编程的客户端和服务器端主要步骤、利用Java语言用到的主要类及其主要作用、TCP和UDP编程的主要差异和特点、你所实现的文件传输的程序代码、实验过程和实验结果。
一,TCP的socket编程
注意,先运行服务端程序,再运行客户端程序输入字母
客户端程序:(实验步骤及其,类功能的解释)
//客户端:
package cn.itcast.util;
import java.io.*;
import java.net.*;
class TCPClient{
public static void main(String argv[]) throws Exception
{
String sentence;//声明字符串变量用于存储字符串输入和传送
String modifiedSentence;//从服务器得到,并送到用户标准输出
System.out.println("请输入将要转换的字符串");
BufferedReader infromUser = new BufferedReader(
new InputStreamReader(System.in));//将流连接到标准输入 inFromUser程序的输入流
Socket clientSocket = new Socket("127.0.0.1",6789);//clientSocket为定义的套接字
DataOutputStream outToServer = new DataOutputStream(
clientSocket.getOutputStream()); //DataOutputStream包含在java.io.*包中
BufferedReader infromServer = new BufferedReader(new InputStreamReader(
clientSocket.getInputStream()));
//inFromServer连接套接字的输入流, BufferedReader包含在java.io.*包中
sentence = infromUser.readLine(); //将用户输入的一行读入到sentence中
outToServer.writeBytes(sentence + '\n');//outToServer程序的输出流
modifiedSentence = infromServer.readLine();//当到达服务器时,他们通过服务器端已将该字符串转换完成
System.out.println("通过服务器端已将该字符串转换完成");
System.out.println("FROM SERVER:"+
modifiedSentence);//将服务器返回的内容显示
clientSocket.close(); //关闭套接字,tcp连接也随之关闭
}
}
服务端程序:(实验步骤及其,类功能的解释)
package cn.itcast.util;
import java.io.*;
import java.net.*;
class TCPServer{
public static void main(String argv[]) throws Exception
{
String ClientSentence;//声明字符串变量用于存储字符串输入和传送
String capitalizedSentence;//从客户端得到的输入内容
ServerSocket welcomeSocket = new ServerSocket(6789);//创建welcomeSocket对象,并在6789端口监听
while(true){
Socket connectionSocket = welcomeSocket.accept();//获取从客户传来的字符
BufferedReader infromClient = new BufferedReader(new InputStreamReader(
connectionSocket. getInputStream()));//创建缓冲输入流对象
DataOutputStream outToClient =
new DataOutputStream(connectionSocket.getOutputStream());//创建缓冲输出流对象
ClientSentence = infromClient. readLine();//按行读取用户输入等待信息
capitalizedSentence = ClientSentence.toUpperCase() + "\n";//将用户输入的字母进行转化
outToClient.writeBytes(capitalizedSentence);
}
}
}
实验结果截图:
二,UDP的socket编程
客户端程序:(实验步骤及其,类功能的解释)
package cn.itcast.util;
import java.io.*;
import java.net.*;
class UDPClient {
public static void main(String args[]) throws Exception
{
BufferedReader inFromUser =
new BufferedReader(new InputStreamReader(System.in));//创建缓冲输入流对象
DatagramSocket clientSocket = new DatagramSocket();//创建DatagramSocket对象
InetAddress IPAddress = InetAddress.getByName("127.0.0.1");//创建本机ip地址对象
byte[] sendData = new byte[1024];//用来存储要发送给服务器的数据
byte[] receiveData = new byte[1024];//用来接收从服务器,返回来的数据
String sentence = inFromUser.readLine();//从键盘按行读取输入数据
sendData = sentence.getBytes();//将输入的数据保存到数组sendData中
DatagramPacket sendPacket =
new DatagramPacket(sendData, sendData.length, IPAddress, 9876);
//创建DatagramPacket对象,初始化发送包的基本信息
clientSocket.send(sendPacket);//将封装好的数据包对象发送给服务器
DatagramPacket receivePacket =
new DatagramPacket(receiveData, receiveData.length);//创建接收包对象
clientSocket.receive(receivePacket);//从服务端上接收,返回来的数据包
String modifiedSentence =
new String(receivePacket.getData());//将数据包的比特流转化为String类型
System.out.println("FROM SERVER:" + modifiedSentence);//将数据信息进行打印
clientSocket.close();//关闭套接字,tcp连接也随之关闭
}
服务端程序:(实验步骤及其,类功能的解释)
package cn.itcast.util;
import java.io.*;
import java.net.*;
class UDPServer {
public static void main(String args[]) throws Exception
{
DatagramSocket serverSocket = new DatagramSocket(9876);//创建serverSocket对象,并在9876端口监听
byte[] sendData = new byte[1024];//用来存储要发送给服务器的数据
byte[] receiveData = new byte[1024];//用来接收从服务器,返回来的数据
while(true)
{
DatagramPacket receivePacket =
new DatagramPacket(receiveData, receiveData.length);//创建接收包对象
serverSocket.receive(receivePacket);//从客户端上接收,发送来的数据包
String sentence = new String(receivePacket.getData());//将数据包的比特流转化为String类型
InetAddress IPAddress = receivePacket.getAddress();//获取客户端的ip地址
int port = receivePacket.getPort();//获取客户端的端口号
String capitalizedSentence = sentence.toUpperCase();//对数据进行大小写转化
sendData = capitalizedSentence.getBytes();//将转化之后的数据转化成比特流
DatagramPacket sendPacket =
new DatagramPacket(sendData, sendData.length, IPAddress, port);//创建DatagramPacket对象,初始化发送包的基本信息
serverSocket.send(sendPacket);//将数据发给客户端
}
}
}
实验结果: