Socket实现服务器与客户端的交互

  
连接过程:
 
根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认。
(1)服务器监听:是服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态。
(2)客户端请求:是指由客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
(3)连接确认:是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求,它就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。
socket连接过程图解
 
demo:
 
 
Client客户端:
import java.io.*;
import java.net.Socket;
import java.util.Scanner;

/**
 * Created by Administrator on 2017/6/27.
 * 客户端
 */
public class Client {
    public static void main(String[] args) {
        Socket socket = null;
        OutputStream os = null;
        //PrintWriter pw = null;
        Scanner scanner = null;
        InputStream is = null;
        BufferedReader br = null;
        try {
            //创建客户端Socket,指定服务器地址和端口
            socket = new Socket("localhost", 8888);
            //获取输出流,向服务器发送信息
            os = socket.getOutputStream();//字节输出流
           // pw = new PrintWriter(os);//将输出流包装为打印流
           // pw.write("用户名:cw,密码:0813");
           // pw.flush();
            System.out.println("客户端,请输入多个字符:");
            scanner = new Scanner(System.in);
            String str = scanner.next();
            os.write(str.getBytes());
            os.flush();
            //socket.shutdownInput();

            //获取输入流,并读取服务器端的响应信息
//            is = socket.getInputStream();
//            br = new BufferedReader(new InputStreamReader(is));
//            String info = null;
//            while ((info = br.readLine()) != null) {
//                System.out.println("服务器:" + info);
//                info=br.readLine();
//            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (scanner != null) {
                scanner.close();
            }

          /*  if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }*/

        }
    }
}

Server服务器端:

import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
/** * Created by Administrator on 2017/6/27. * 基于TCP协议的Socket通信,实现用户登陆 * 服务器端 */
public class Server {
    public static void main(String[] args) {
        try{
            //创建一个服务器端Socket,指定并监听端口            
            ServerSocket serverSocket=new ServerSocket(8888);            
            Socket socket=null;            int count =0;            
            System.out.println("*****服务器即将启动,等待客户端的连接*****");            
            //循环监听等待客户端的连接           
             while(true){
                //调用accept()方法开始监听,等待客户端的连接                
                socket = serverSocket.accept();                
                //创建一个线程                
                ServerThread serverThread=new ServerThread(socket);                
                //启动线程                
                serverThread.start();                
                count++;                
                System.out.println("客户端的数量:"+count);                
                InetAddress address = socket.getInetAddress();                
                System.out.println("当前客户端的IP:"+address.getHostAddress());            }
        }catch (Exception e){
            e.printStackTrace();        }
    }
}
 
ServerThread线程:
  

 
连接过程:
 
根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认。
(1)服务器监听:是服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态。
(2)客户端请求:是指由客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
(3)连接确认:是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求,它就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。
socket连接过程图解
 


demo:
 
 
Client客户端:


import java.io.*;
import java.net.Socket;
import java.util.Scanner;

/**
 * Created by Administrator on 2017/6/27.
 * 客户端
 */
public class Client {
    public static void main(String[] args) {
        Socket socket = null;
        OutputStream os = null;
        //PrintWriter pw = null;
        Scanner scanner = null;
        InputStream is = null;
        BufferedReader br = null;
        try {
            //创建客户端Socket,指定服务器地址和端口
            socket = new Socket("localhost", 8888);
            //获取输出流,向服务器发送信息
            os = socket.getOutputStream();//字节输出流
           // pw = new PrintWriter(os);//将输出流包装为打印流
           // pw.write("用户名:cw,密码:0813");
           // pw.flush();
            System.out.println("客户端,请输入多个字符:");
            scanner = new Scanner(System.in);
            String str = scanner.next();
            os.write(str.getBytes());
            os.flush();
            //socket.shutdownInput();

            //获取输入流,并读取服务器端的响应信息
//            is = socket.getInputStream();
//            br = new BufferedReader(new InputStreamReader(is));
//            String info = null;
//            while ((info = br.readLine()) != null) {
//                System.out.println("服务器:" + info);
//                info=br.readLine();
//            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (scanner != null) {
                scanner.close();
            }

          /*  if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }*/

        }
    }
}

Server服务器端:

import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
/** * Created by Administrator on 2017/6/27. * 基于TCP协议的Socket通信,实现用户登陆 * 服务器端 */
public class Server {
    public static void main(String[] args) {
        try{
            //创建一个服务器端Socket,指定并监听端口            
            ServerSocket serverSocket=new ServerSocket(8888);            
            Socket socket=null;            int count =0;            
            System.out.println("*****服务器即将启动,等待客户端的连接*****");            
            //循环监听等待客户端的连接           
             while(true){
                //调用accept()方法开始监听,等待客户端的连接                
                socket = serverSocket.accept();                
                //创建一个线程                
                ServerThread serverThread=new ServerThread(socket);                
                //启动线程                
                serverThread.start();                
                count++;                
                System.out.println("客户端的数量:"+count);                
                InetAddress address = socket.getInetAddress();                
                System.out.println("当前客户端的IP:"+address.getHostAddress());            }
        }catch (Exception e){
            e.printStackTrace();        }
    }
}


 
ServerThread线程:

import java.io.*;
import java.net.Socket;
import java.util.Scanner;

/**
 * Created by Administrator on 2017/6/27.
 * 服务器线程处理类
 */
public class ServerThread extends Thread {
    //和本线程相关的Socket
    Socket socket = null;

    public ServerThread(Socket socket) {
        this.socket = socket;
    }

    //线程执行的操作,响应客户端的请求2
    @Override
    public void run() {
        InputStream is = null;
        InputStreamReader isr = null;
        BufferedReader br = null;
        OutputStream os = null;
        //PrintWriter pw = null;
        Scanner scanner = null;
        try {
            System.out.println("*****线程****");
            //获取输入流,并读取客户端信息
            is = socket.getInputStream();
            isr = new InputStreamReader(is);
            br = new BufferedReader(isr);
            String info = null;
            while ((info = br.readLine()) != null) {//循环读取客户端信息
                System.out.println("来自客户端:" + info);
                br.readLine();
            }
           // socket.shutdownInput();

            //socket.shutdownInput();

            //获取输出流,响应服务端的请求
            os = socket.getOutputStream();
            System.out.println("服务器,请输入多个字符:");
            scanner = new Scanner(System.in);
            String str = scanner.next();
            os.write(str.getBytes());

           // os.flush();
           // pw = new PrintWriter(os);
            //pw.write("elcome!");
           // pw.flush();

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (isr != null) {
                try {
                    isr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {                     
                    e.printStackTrace();                
                }             
             }             
             
             
            if (scanner != null) {                 
               scanner.close();           
             }             
             
            if (socket != null) {                 
              try {                     
                 socket.close();                
              } catch (IOException e) {                    
                    e.printStackTrace();                
              }             
            }         
        }     
      }
   }


 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
原文地址:https://www.cnblogs.com/wang-chen/p/9109829.html