java网络编程(3)TCP

  1. 使用TCP进行网络数据传输的时候,TCP会在需要传输数据的两端建立两个Socket(插座),并且在两个Socket之间建立一条虚拟链路,然后这两台主机就可以进行通信了。
  2. 下面是一个很简单的例子。
    1. Server类创建一个ServerSocket对象,用于监听客户端Socket的链接请求,这如果接受到请求的话,Server类就会创建一个Socket,并且将消息打印出来。
    2. Client类像服务器发送请求并且将数据打印
      import java.io.IOException;
      import java.io.PrintStream;
      import java.net.ServerSocket;
      import java.net.Socket;
      
      public class Server {
      public static void main(String args[]) throws IOException {
          
          ServerSocket ss = new ServerSocket(30000);
      //    创建一个ServerSocket对象,并且保持监听,一旦得到请求,就执行while里的操作
          
          while (true){
              Socket socket = ss.accept();
      //        创建一个Socket对象,通过ServerSocket的accept(),accept方法是如果接受到一个客户端
      //        的链接请求,就返回一个与客户端Socket对应的Socket
              
              PrintStream ps = new  PrintStream(socket.getOutputStream());
      //        将socket的输出流包装成PrintStream对象
              
              ps.println("啦啦啦~");
              
              ps.close();
              socket.close();
          }
          }
      }
      
      import java.io.BufferedReader;
      import java.io.IOException;
      import java.io.InputStreamReader;
      import java.net.Socket;
      
      public class Client {
          public static void main(String args[]) throws IOException{
      
              Socket socket = new Socket("127.0.0.1", 30000);
      //        创建一个Socket对象并且发送请求
      
              BufferedReader br = new BufferedReader( new InputStreamReader(socket.getInputStream()));
      //        读取数据,并且将数据包装成BufferedReader
      
              String line = br.readLine();
              System.out.println("来自服务器的数据: " +line);
              br.close();
              socket.close();
          }
      }
      

      先运行Service,发现程序发生阻塞,因为它在等待客户端的请求,在运行Client,发现程序打印出 “来自服务器的数据: 啦啦啦~”

  3. 使用sock实现的“聊天室”

    1. 原理:

      1. 服务器使用socket保持监听,一旦得到请求就将请求那个客户端的socket加入到事先定义的列表之中,服务器还会不断地向列表中地客户端发送它监听到地socket中地输入流的内容。

      2. 客户端会不断的监听服务器,一旦监听到就打印出服务器socket中输入流的内容

    2. 代码示例

      import java.io.IOException;
      import java.net.ServerSocket;
      import java.net.Socket;
      import java.util.ArrayList;
      
      public class MyServer {
          public static ArrayList<Socket> socketList = new ArrayList<>();
      //    创建一个Socket列表,将客户端的Socket保存在列表中,通过遍历Socket列表就可以像所有客户端发送信息
      
          public static void main(String args[]) throws IOException {
      
      
      //定义一个socket并且保持监听,当收到请求之后,就将客户端的socket加入到列表中,并且创建一个线程为该客户端服务
              ServerSocket ss = new ServerSocket(30000);
              while(true){
                  Socket s = ss.accept();
                  socketList.add(s);
                  new Thread(new ServerThread(s)).start();
              }
          }
      }
      
      import java.io.BufferedReader;
      import java.io.IOException;
      import java.io.InputStreamReader;
      import java.io.PrintStream;
      import java.net.Socket;
      
      public class ServerThread implements Runnable {
      
          Socket s = null;
      //    定义当前线程的socket
      
          BufferedReader br = null;
      //  定义处理的cocket对应的输入流
      
      //    构造方法,将socket对应的输入流赋值给br
          public ServerThread(Socket s) throws IOException {
              this.s = s;
              br = new BufferedReader(new InputStreamReader(s.getInputStream()));
          }
      
          public void run(){
              try{
                  String content = null;
                  while((content = readFromClient()) != null){
      //                将从客户端读取到的数据发送给每一个客户端
      
                      for(Socket s : MyServer.socketList){
                          PrintStream ps = new PrintStream(s.getOutputStream());
                          ps.println(content);
                      }
                  }
              }catch (IOException e){
                  e.printStackTrace();
              }
          }
          private String readFromClient(){
              try{
      
                  return br.readLine();
      //      通过socket读取从客户端发送过来的数据
      
              }catch (IOException e){
                  MyServer.socketList.remove(s);
              }
              return null;
          }
      }
      
      import java.io.BufferedReader;
      import java.io.InputStreamReader;
      import java.io.PrintStream;
      import java.net.Socket;
      
      public class MyClient {
          public static void main(String args[]) throws  Exception{
      
              Socket s = new Socket("127.0.0.1", 30000);
      
              new Thread(new ClientThread(s)).start();
      //        客户端启用ClientThread不断地从服务器读取数据
      
      //        一下为获取输出流并打印
              PrintStream ps = new PrintStream(s.getOutputStream());
              String line = null;
              BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
              while((line = br.readLine()) != null){
                  ps.println(line);
              }
          }
      }
      
      import java.io.BufferedReader;
      import java.io.IOException;
      import java.io.InputStreamReader;
      import java.net.Socket;
      
      public class ClientThread implements Runnable{
      
          private Socket s;
          BufferedReader br = null;
          public ClientThread(Socket s) throws IOException{
              this.s = s;
              br = new BufferedReader(new InputStreamReader(s.getInputStream()));
          }
          public void run(){
              try{
                  String content = null;
                  while((content = br.readLine()) !=null ){
      //              不断获取socket输入流的内容,并且打印到控制台
      
                      System.out.println(content);
                  }
              }catch (Exception e){
                  e.printStackTrace();
              }
          }
      
      }
      

       

    3. 运行:先运行MySever类,然后运行几个MyClient类,在MyClient对应的控制台中输入信息,可以看到所有的MyClient对应的控制台都打印出信息

  4. 这是我看李刚编著的《疯狂Java讲义》后总结出来的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值