这里我们通过一个用户登录的例子来学习基于 TCP 协议的 Socket 通信。

先通过下面一系列的图看了解一下Socket通信原理吧!
通过 Socket 实现 TCP 编程入门_JavaSE

Socket通信模型

通过 Socket 实现 TCP 编程入门_JavaSE_02
通过 Socket 实现 TCP 编程入门_JavaSE_03

ServerSocket 构造器和成员方法

1、ServerSocket 构造方法
讲解:
①下面的backlog(积压的意思是指服务端同时允许和多少个客户端进行通信的数量)
②下面的第4个构造方法该构造方法就是在第三种构造方法的基础上,还制定了相关的IP地址,这种情况适用于计算机上有多块网卡和多个IP的情况,我们可以明确规定ServerSocket在那块网卡或者IP地址上等待客户的连接请求,显然对于只有一块网卡的情况我们就不用专门指定了。
通过 Socket 实现 TCP 编程入门_JavaSE_04

2、ServerSocket 成员方法
通过 Socket 实现 TCP 编程入门_JavaSE_05

Socket 构造器和成员方法

1、Socket 构造器
通过 Socket 实现 TCP 编程入门_JavaSE_06
2、Socket 成员方法
通过 Socket 实现 TCP 编程入门_JavaSE_07
通过 Socket 实现 TCP 编程入门_JavaSE_08
通过 Socket 实现 TCP 编程入门_JavaSE_09

一个服务端和支持多个客户端的对话demo

代码如下:
1、server.java

import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

/**
 *
 * 基于TCP协议的Socket通信,实现用户登录
 * 服务端
 * @autho 196432
 * @date 2017/12/4 下午7:37
 */
public class Server {
    public static void main(String args[]) {
        try {
            //1、创建一个服务端Socket,即ServerSocket,指定绑定的端口,并监听此端口
            ServerSocket serverSocket = new ServerSocket(8888);
            Socket socket = null;
            //记录客户端的数量
            int count = 0;
            //2、调用accept方法开始监听,等待客户端的连接
            System.out.println("***服务端即将启动,等待客户端的连接****");
            //循环监听等待客户端的连接
            while(true) {
                //调用accept()方法开始监听,等待客户端的连接
                socket = serverSocket.accept();
                //创建一个新的线程
                ServerThread serverThread = new ServerThread(socket);
                //启动线程
                serverThread.start();
                count ++;//统计客户端的数量
                System.out.println("客户端的数量:"+count);
                InetAddress inetAddress = socket.getInetAddress();
                System.out.println("当前客户端的IP:"+inetAddress.getHostAddress());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2、ServerThread.java

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

/**
 * 服务器线程处理类
 * @author 196432
 * @date 2017/12/4 下午8:32
 */
public class ServerThread extends Thread {
    //本线程相关的Socket
    Socket socket = null;
    public ServerThread(Socket socket) {
        this.socket = socket;
    }
    //线程执行操作,响应客户端的请求
    public void run() {
        InputStream inputStream = null;//字符输入流
        InputStreamReader inputStreamReader = null;
        BufferedReader bufferedReader = null;
        OutputStream outputStream = null;
        PrintWriter printWriter = null;
        try {
            //获取输入流,并读取客户端信息
            inputStream = socket.getInputStream();
            inputStreamReader = new InputStreamReader(inputStream);//将字节流转换成字符流
            bufferedReader = new BufferedReader(inputStreamReader);//为字符流添加缓存
            String info = null;
            while((info = bufferedReader.readLine()) != null) {
                System.out.println("我是服务器,我接收到客户端发过来的消息是:"+info);
            }
            socket.shutdownInput();//关闭输入流(解释:因为把从客户端发过来的消息已经读完了,所以关闭)
            //获取输出流,响应客户端的请求
            outputStream = socket.getOutputStream();//获得往socket里面写数据的输出流
            printWriter = new PrintWriter(outputStream);
            printWriter.write("欢迎您!");
            printWriter.flush();//刷新缓存
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭资源
            try {
                if(bufferedReader != null) {
                    bufferedReader.close();
                }
                if(outputStream != null) {
                    outputStream.close();
                }
                if(inputStreamReader != null) {
                    inputStreamReader.close();
                }
                if(inputStream != null) {
                    inputStream.close();
                }
                if(socket != null) {
                    socket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

3、Client.java

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

/**
 * 客户端
 * @author 196432
 * @date 2017/12/4 下午7:37
 */
public class Client {
    public static void main(String args[]) {
        try {
            //1、创建客户端Socket,指定要连接的服务器地址和端口
            Socket socket = new Socket("localhost",8888);
            //2、获取输出流,向服务器端发送信息
            OutputStream outputStream = socket.getOutputStream();//字节输出流
            PrintWriter printWriter = new PrintWriter(outputStream);//将输出流包装为打印流
            Scanner scanner = new Scanner(System.in);
            String s=new String(scanner.nextLine());
            printWriter.write("用户名:Tom;密码:123456");
            printWriter.flush();//刷新缓存,输出信息
            socket.shutdownOutput();//关闭输出流
            //3、获取输入流,并读取服务器的响应信息
            InputStream inputStream = socket.getInputStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            String info = null;
            while((info = bufferedReader.readLine()) != null) {
                System.out.println("我是客户端,我接收到服务器发过来的信息是:"+info);
            }
            //4、 关闭资源
            printWriter.close();
            bufferedReader.close();
            inputStream.close();
            outputStream.close();
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}