Java第九次作业

仿照例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

上一篇:FFmpeg原理介绍与代码实现


下一篇:(音视频学习笔记):FFmpeg内存模型及AVPacket、AVFrame常用API