1.仿照例15.4,编写基于Socket的多客户/服务器通信程序。
//客户端 import java.io.*; import java.net.*; public class client3 { public static void main(String[] args) { try{ Socket socket=new Socket("127.0.0.1",4700); BufferedReader sin=new BufferedReader(new InputStreamReader(System.in)); PrintWriter os= new PrintWriter(socket.getOutputStream()); BufferedReader is=new BufferedReader((new InputStreamReader(socket.getInputStream()))); String readline; readline=sin.readLine(); while(!readline.equals("bye")){ os.println(readline); os.flush(); System.out.println("Client:"+readline); System.out.println("server:"+is.readLine()); readline=sin.readLine(); } os.close(); is.close(); socket.close(); }catch(Exception e){ System.out.println("Error:"+e); } } }
//服务端 package socket; import java.io.*; import java.net.*; 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);//出错,打印出错信息 } } } 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 socket.ServerThread(serverSocket.accept(),clientnum).start(); clientnum++; //增加客户计数 } serverSocket.close(); //关闭ServerSocket } }
2.仿照例15.5,编写基于数据报的多客户/服务器通信程序。
//客户端 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(); //关闭数据报套接字 } }