加入收藏 | 设为首页 | 会员中心 | 我要投稿 汽车网 (https://www.0577qiche.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 教程 > 正文

Java IO学习笔记四:Socket基础

发布时间:2023-04-18 14:18:17 所属栏目:教程 来源:
导读:准备两个Linux实例(安装好jdk1.8),我准备的两个实例的ip地址分别为:

io1实例:192.168.205.138
io2实例:192.168.205.149

安装必要工具:

yum install -y strace lsof pmap tcpdump
准备服务端代码
准备两个Linux实例(安装好jdk1.8),我准备的两个实例的ip地址分别为:

io1实例:192.168.205.138
io2实例:192.168.205.149

安装必要工具:

yum install -y strace lsof  pmap tcpdump
准备服务端代码

import java.io.*;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.socket;
/**
 * BIO Socket Server
 */
public class SocketServerBIOTest {
    private static final int PORT = 9090;
    private static final int BACK_LOG = 2;
    public static void main(String[] args) {
        ServerSocket server = null;
        try {
            server = new ServerSocket();
            server.bind(new InetSocketAddress(PORT), BACK_LOG);
            System.out.println("server started , port : " + PORT);
        } catch (IOException e) {
            e.printstacktrace();
        }
        try {
            // 接受客户端连接
            while (true) {
                // 先阻塞,这样客户端暂时无法连接进来
                system.in.read();
                // 这个方法也是阻塞的,如果没有客户端连接进来,会一直阻塞在这里,除非设置了超时时间
                Socket client = server.accept();
                System.out.println("client " + client.getPort() + " connected!!!");
                // 客户端连接进来后,开辟一个新的线程去接收并处理
                new Thread(() -> {
                    try {
                        InputStream inputStream = client.getInputStream();
                        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                        char[] data = new char[1024];
                        while (true) {
                            int num = reader.read(data);
                            if (num > 0) {
                                System.out.println("client read some data is :" + num + " val :" + new String(data, 0, num));
                            } else if (num == 0) {
                                System.out.println("client read nothing!");
                                continue;
                            } else {
                                System.out.println("client read -1...");
                                system.in.read();
                                client.close();
                                break;
                            }
                        }
                    } catch (Exception e) {
                        e.printstacktrace();
                    }
                }).start();
            }
        } catch (Exception e) {
            e.printstacktrace();
        } finally {
            try {
                server.close();
            } catch (IOException e) {
                e.printstacktrace();
            }
        }
    }
}
死循环中,由于第一句:

system.in.read();
导致

Socket client = server.accept();
无法执行,即:服务端此时是无法接收客户端的。

准备客户端代码:

import java.io.*;
import java.net.socket;
/**
 * Socket Client
 */
public class SocketClientTest {
    public static void main(String[] args) {
        try {
            Socket client = new Socket("192.168.205.138", 9090);
            OutputStream out = client.getoutputStream();
            InputStream in = system.in;
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            while (true) {
                String line = reader.readLine();
                if (line != null) {
                    byte[] bb = line.getBytes();
                    for (byte b : bb) {
                        out.write(b);
                    }
                }
            }
        } catch (IOException e) {
            e.printstacktrace();
        }
    }
}
在实例io1中启动服务端代码:

javac SocketServerBIOTest.java && java SocketServerBIOTest
在io1中开启抓包工具:

tcpdump -nn -i ens33 port 9090
在io2中执行客户端代码:

javac SocketClientTest.java && java SocketClientTest
由于我们在服务端加了一段:

system.in.read()
方法,导致服务端其实没办法执行accept()

但是在服务端查看抓包信息:

[root@io socket]# tcpdump -nn -i ens33 port 9090
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
15:19:56.021974 IP 192.168.205.149.56944 > 192.168.205.138.9090: Flags [S], seq 391962776, win 29200, options [mss 1460,sackOK,TS val 16515471 ecr 0,nop,wscale 7], length 0
15:19:56.022035 IP 192.168.205.138.9090 > 192.168.205.149.56944: Flags [S.], seq 2744580571, ack 391962777, win 28960, options [mss 1460,sackOK,TS val 16517545 ecr 16515471,nop,wscale 7], length 0
15:19:56.022349 IP 192.168.205.149.56944 > 192.168.205.138.9090: Flags [.], ack 1, win 229, options [nop,nop,TS val 16515472 ecr 16517545], length 0
内核已经为客户端和服务端建立了连接并完成了三次握手,在服务端使用netstat查看:

[root@io socket]# netstat -ntap
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
...
tcp6       0      0 192.168.205.138:9090    192.168.205.149:56944   ESTABLISHED -          
...

(编辑:汽车网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章