仿照例15.4,编写基于TCP Socket的多客户/服务器通信程序。
import java.io.*; import java.net.*; public class ServerThread extends Thread{ Socket socket=null; //保存与本线程相关的Socket对象 int clientnum; //保存本线程的客户计数 public ServerThread(Socket socket,int num) { //构造函数 this.socket=socket; //初始化socket变量 clientnum=num+1; //初始化clientnum变量 } public void run() { //线程主体 try{ String line; BufferedReader is=new BufferedReader(new InputStreamReader(socket.getInputStream())); PrintWriter os=new PrintWriter(socket.getOutputStream()); BufferedReader sin=new BufferedReader(new InputStreamReader(System.in)); System.out.println("Client:"+ clientnum +is.readLine()); line=sin.readLine(); while(!line.equals("bye")){//如果该字符串为 "bye",则停止循环 os.println(line);//向客户端输出该字符串 os.flush();//刷新输出流,使Client马上收到该字符串 System.out.println("Server:"+line); System.out.println("Client:"+ clientnum +is.readLine()); line=sin.readLine();//从系统标准输入读入一字符串 }//继续循环 os.close(); //关闭Socket输出流 is.close(); //关闭Socket输入流 socket.close(); //关闭Socket }catch(Exception e){ System.out.println("Error:"+e);//出错,打印出错信息 } } }
import java.io.*; import java.net.*; public class MultiTalkServer{ static int clientnum=0; //静态成员变量,记录当前客户的个数 public static void main(String args[]) throws IOException { ServerSocket serverSocket=null; boolean listening=true; try{ //创建一个ServerSocket在端口4700监听客户请求 serverSocket=new ServerSocket(4700); }catch(IOException e) { System.out.println("Could not listen on port:4700."); System.exit(-1); //退出 } while(listening){ //循环监听 //监听到客户请求,根据得到的Socket对象和客户计数创建服务线程,并启动之 new ServerThread(serverSocket.accept(),clientnum).start(); clientnum++; //增加客户计数 } serverSocket.close(); //关闭ServerSocket } }
仿照例15.5,编写基于UDP数据报的多客户/服务器通信程序。
import java.io.*; import java.net.*; public class QuoteClient { public static void main(String[] args) throws IOException{ if(args.length!=1){ //如果启动的时候没有给出Server的名字,那么打印出错信息并退出 System.out.println("Usage:java QuoteClient <hostname>"); return; } DatagramSocket socket=new DatagramSocket();//创建数据报套接字 byte[] buf=new byte[256]; //创建缓冲区 buf = "hello".getBytes(); InetAddress address=InetAddress.getByName(args[0]); //创建DatagramPacket对象 DatagramPacket packet=new DatagramPacket(buf, buf.length, address, 4445); socket.send(packet); //发送 //创建新的DatagramPacket对象,用来接收数据报 packet=new DatagramPacket(buf,buf.length); socket.receive(packet); //接收 //根据接收到的字节数组生成相应的字符串 String received=new String(packet.getData()); //打印生成的字符串 System.out.println("Quote of the Moment:"+received ); //关闭套接口 socket.close(); } }
public class QuoteServer{ public static void main(String args[]) throws IOException { new QuoteServerThread().start();//启动一个QuoteServerThread线程 } }
import java.io.*; import java.net.*; public class QuoteServerThread extends Thread { protected DatagramSocket socket=null;//本线程关联的DatagramSocket对象 protected BufferedReader in=null; //用来读文件的一个Reader protected boolean moreQuotes=true; //标志变量,是否继续操作 public QuoteServerThread() throws IOException { //无参数的构造方法 this("QuoteServerThread"); } public QuoteServerThread(String name) throws IOException { super(name); //调用父类的构造方法 socket=new DatagramSocket(4445);//在端口4445创建数据报套接字 in= new BufferedReader(new InputStreamReader(System.in));} public void run() {//线程主体 while(moreQuotes) { try{ byte[] buf=new byte[256]; //创建缓冲区 DatagramPacket packet=new DatagramPacket(buf,buf.length); socket.receive(packet); //接收数据报 System.out.println(new String(packet.getData())); String dString= in.readLine(); //终端输入字符串 //如果是bye,则向客户端发完消息后退出 if(dString.equals("bye")){ moreQuotes=false;} buf=dString.getBytes();//把String转换成字节数组,以便传送 InetAddress address = packet.getAddress(); //Client地址 int port=packet.getPort(); // Client端口号 //构建发送DatagramPacket对象 packet=new DatagramPacket(buf,buf.length,address,port); socket.send(packet); //发送数据报 }catch(IOException e) { //异常处理 e.printStackTrace(); //打印错误栈 moreQuotes=false; //标志变量置false,以结束循环 }} socket.close(); //关闭数据报套接字}}
基于TCP Socket的C/S通信与基于UDP数据报的C/S通信有哪些区别?Java分别提供了哪些支持?
TCP | UDP | |
传输数据可靠性 | TCP是一个可靠的协议,它能确保接收方完全正确地获取发送方所发送的全部数据。 | UDP是一个不可靠的协议,发送方所发送的数据报并不一定以相同的次序到达接收方,也不能保证接收方一定能收到。 |
通讯 方式 | 进行数据传输之前必然要建立连接,发送方与接收方在该连接之上传递数据。 | 发送方和接收方未建立连接,每个数据报中都给出了完整的地址信息。 |
传输数据量 | 一旦连接建立起来,双方的socket就可以按统一的格式传输大量的数据。 | 传输数据时有大小限制,每个被传输的数据报必须限定在64KB之内。 |
特点 | TCP传输量大,可靠性强。 | UDP操作简单,传输效率高。 |
Java 支持 | ServerSocket Socket | DatagramSocket DatagramPacket |