字符流输出时如果用os.wirte输出,接受端要只能用字节流接受
字符流输出时如果用os.println输出,接受端可用字节流接受,也可用字符流接受
os.println()只能输出字符或者字符串,如果是字节,接受端解析不出来
is.readLine(),是字符输出流独有的,直接输出内容,直接输出流没有此方法
new String(Byte[]),接受字节流的数据读取,与byte[] byteData = new byte[1024 * 1024]一起使用;
接受流都用缓存流来接受:
输入字符缓存流:BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
输入字节缓存流:BufferedInputStream reader = new BufferedInputStream(socket.getInputStream());
输出字符流:PrintWriter pw = new PrintWriter(socket.getOutputStream());
输出字节流:PrintStream pw = new PrintStream(socket.getOutputStream());
accept()方法会阻塞一直等待客户端链接才可往下执行
read(),readLine()也会阻塞,等待数据传输和链接,如果忽然断电或者断网,或一直卡住在等待,可以设置一直链接超时时间,例如设置超时5秒抛出异常,socket.setSoTimeout(5000);

1:简单的一次(字符) 通讯ServerSocket

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

public class TcpServer{
    public static void main(String[] args) {
        try {
            //创建一个serverSocket监听一个8080端口
            ServerSocket server = new ServerSocket(8089);
            //等待请求
            Socket socket = server.accept();
            //接收到请求后使用socket通信
            BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String line = reader.readLine();
            System.out.println("收到客户端信息:" + line);
            //向客户端发送信息
            PrintWriter pw = new PrintWriter(socket.getOutputStream());
            pw.println("我收到了信息:" + line);
            pw.flush();
            pw.close();
            reader.close();
            socket.close();
            server.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

2:简单的一次(字符) 通讯Socket

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

public class TcpClient {


    public static void main(String[] args) {
        String msg = "我是客户端";
        try {
            Socket cli = new Socket("127.0.0.1", 8089);
            PrintWriter pw = new PrintWriter(cli.getOutputStream());
            BufferedReader br = new BufferedReader(new InputStreamReader(cli.getInputStream()));
            pw.println(msg);
            pw.flush();
            String line = br.readLine();
            System.out.println("收到服务端信息:" + line);
            pw.close();
            br.close();
            cli.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

3:简单的一次(字节) 通讯ServerSocket

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

public class MyClass {
    public static void main(String[] args) {
        try {
            //创建一个serverSocket监听一个8080端口
            ServerSocket server = new ServerSocket(8089);
            //等待请求
            Socket socket = server.accept();
            byte[] byteData = new byte[1024 * 1024];
            //接收到请求后使用socket通信
            BufferedInputStream reader = new BufferedInputStream(socket.getInputStream());
            int line = reader.read(byteData);
            System.out.println("收到客户端信息:" + new String(byteData));
            //向客户端发送信息
            PrintStream pw = new PrintStream(socket.getOutputStream());
            String out="我收到了信息:";
            pw.write(out.getBytes());
            pw.flush();
            pw.close();
            reader.close();
            socket.close();
            server.close();

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

4:简单的一次(字节) 通讯Socket

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

public class TcpClient {
    public static void main(String[] args) {
        String msg = "我是客户端";
        try {
            Socket cli = new Socket("127.0.0.1", 8089);
            byte[] byteData = new byte[1024 * 1024];
            PrintStream pw = new PrintStream(cli.getOutputStream());
            BufferedInputStream br = new BufferedInputStream(cli.getInputStream());
            pw.write(msg.getBytes());
            pw.flush();
            int line = br.read(byteData);
            System.out.println("收到服务端信息:" + new String(byteData));
            pw.close();
            br.close();
            cli.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

5:支持多设备(字节) 通讯ServerSocket

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

public class MyClass {
    public static void main(String[] args) {
        try {
            //创建一个serverSocket监听一个8080端口
            final ServerSocket server = new ServerSocket(8089);
            //等待请求
            while (true) {
                final Socket socket = server.accept();
                //设置read读取超时时间
                socket.setSoTimeout(5000);
                final byte[] byteData = new byte[1024 * 1024];
                //接收到请求后使用socket通信
                new Thread(new Runnable() {
                    public void run() {
                        try {
                            BufferedInputStream reader = new BufferedInputStream(socket.getInputStream());
                            int line = reader.read(byteData);
                            System.out.println("收到客户端信息:" + new String(byteData).trim());
                            //向客户端发送信息
                            PrintStream pw = new PrintStream(socket.getOutputStream());
                            String out = "我收到了信息:";
                            pw.write(out.getBytes());
                            pw.flush();
                            pw.close();
                            reader.close();
                            socket.close();
                        }catch (Exception e){
                            e.printStackTrace();
                        }
                    }
                }).start();
            }

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

6:TCP客户端,推荐这种做法

public static void main(String[] args) throws Exception {
    String serverHostname = "127.0.0.1"; // 服务器IP地址
    int serverPort = 6789; // 服务器端口号
    // 建立TCP连接
    Socket clientSocket = new Socket(serverHostname, serverPort);
    // 发送数据
    OutputStream outToServer = clientSocket.getOutputStream();
    DataOutputStream out = new DataOutputStream(outToServer);
    String message = "Hello, server!";
    out.writeUTF(message);
    // 接收响应
    InputStream inFromServer = clientSocket.getInputStream();
    DataInputStream in = new DataInputStream(inFromServer);
    String responseMessage = in.readUTF();
    System.out.println("Response message from server: " + responseMessage);
    // 关闭连接
    clientSocket.close();
}

7:TCP服务端,推荐这种做法

public static void main(String[] args) throws Exception {
    int serverPort = 6789;
    // 建立TCP连接
    ServerSocket serverSocket = new ServerSocket(serverPort);
    System.out.println("Waiting for client on port " + serverSocket.getLocalPort() + "...");
    // 等待客户端连接
    Socket server = serverSocket.accept();
    System.out.println("Just connected to " + server.getRemoteSocketAddress());
    // 接收数据
    DataInputStream in = new DataInputStream(server.getInputStream());
    //如果发送的不是字符串,需要用注释的方法接收数据,不然接收不到数据
    //byte[] buffer = new byte[1024];
    //int bytesRead = in.read(buffer);
    //System.out.println("Bytes received: " + bytesRead);
    //String message = new String(buffer, 0, bytesRead, "UTF-8");
    //System.out.println("Message received: " + message);
    
    //只能接收字符串数据
    String message = in.readUTF();
    System.out.println("Message received from client: " + message);
    // 发送响应
    OutputStream outToClient = server.getOutputStream();
    DataOutputStream out = new DataOutputStream(outToClient);
    String responseMessage = "Hello, client!";
    out.writeUTF(responseMessage);
    // 关闭连接
    server.close();
}