java socket入门小例子#入门教程,傻瓜也会#

好吧,这例子其实没那么傻瓜(主要是我解释得没那么详细)。有不懂的不说明你笨哦~欢迎留言交流。

实现的功能:

1,一个客户端,一个服务端。

2,客户端和服务端实现一来一回的收发信息。

后续还会加入GUI和多线程,教程戳这里:java socket 聊天小程序(socket入门小例子进阶版)

客户端:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class TalkToAlicebot {

    BufferedReader bufferedReader;

    ObjectOutputStream out;

    ObjectInputStream in;


    public TalkToAlicebot() throws IOException {
        Socket client;

        try {
            client = new Socket("127.0.0.1", 7777);

            // construct stream 'out' BEFORE 'in'
            out = new ObjectOutputStream(client.getOutputStream());
            out.flush();
            in = new ObjectInputStream(client.getInputStream());

            try {
                do {
                    // DO NOT construct stream here, would cause StreamCorruptedException.
                    // out = new ObjectOutputStream(client.getOutputStream());
                    // out.flush();
                    // in = new ObjectInputStream(client.getInputStream());

                    System.out.println("Waiting for input...");
                    bufferedReader = new BufferedReader(new InputStreamReader(System.in));

                    out.writeObject(bufferedReader.readLine());
                    out.flush();

                    String messageFromServer;

                    System.out.println("Waiting for response...");
                    messageFromServer = (String) in.readObject();

                    System.out.println("Server>" + messageFromServer);

                } while (true);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bufferedReader != null) {
                bufferedReader.close();
            }
            if (out != null) {
                out.close();
            }
            if (in != null) {
                in.close();
            }
        }
    }

    public static void main(String[] args) {

        try {

            new TalkToAlicebot();

        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
服务器端:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Alicebot {

    ServerSocket ss;

    Socket socket;

    ObjectOutputStream out;

    String messageReceived;

    ObjectInputStream in;

    BufferedReader send;

    public Alicebot() throws IOException {
        ss = new ServerSocket(7777);
        System.out.println("Waiting for connection...");

        socket = ss.accept();// blocks until a connection is made

        System.out.println("Connection Established");

        // send
        out = new ObjectOutputStream(socket.getOutputStream());
        out.flush();
        // receive
        System.out.println("Waiting for in stream...");
        in = new ObjectInputStream(socket.getInputStream());
        System.out.println("In stream received! Sending out stream...");

        try {
            while (true) {

                messageReceived = (String) in.readObject();

                System.out.println("From client: " + messageReceived);

                send = new BufferedReader(new InputStreamReader(System.in));
                System.out.println("Waiting for input response...");
                sendMessage(send.readLine());

            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            closeConnection();
        }
    }


    private void closeConnection() {
        try {
            in.close();
            out.close();
            socket.close();
            send.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }


    private void sendMessage(String messageReceived2) {

        try {
            out.writeObject(messageReceived2);
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public static void main(String[] args) {
        try {
            new Alicebot();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

开始写这个小例子的时候,借鉴了网上的类似的东西,即使是这么短的代码,自己搞的时候还是遇到不少问题。确实对socket和输入输出不了解。相关问题总结如下:

1- Connection reset

java.net.SocketException: Connection reset
	at java.net.SocketInputStream.read(SocketInputStream.java:168)
	at java.net.SocketInputStream.read(SocketInputStream.java:182)
	at java.io.ObjectInputStream$PeekInputStream.peek(ObjectInputStream.java:2248)
	at java.io.ObjectInputStream$BlockDataInputStream.peek(ObjectInputStream.java:2541)
	at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2551)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1296)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)

原因:

1,如果一端的Socket被关闭(或主动关闭,或因为异常退出而 引起的关闭),另一端仍发送数据,发送的第一个数据包引发该异常(Connect reset by peer)。

2,一端退出,但退出时并未关闭该连接,另一端如果在从连接中读数据则抛出该异常(Connection reset)。简单的说就是在连接断开后的读和写操作引起的。

2-StreamCorruptedException

我当时出现这个问题,现象是客户端第一次向服务器端发送数据没有问题,第二次就会出现这个异常。

在网上查了一下,是因为在while循环中,每次服务端都new ObjectInputStream(),而客户端没有。而new ObjectInputStream对象时,会去readStreamHeader();将客户端发送过来的数据当做的消息头了,比较出消息头不对所以报错。

    public ObjectOutputStream(OutputStream out) throws IOException {
	verifySubclass();
	bout = new BlockDataOutputStream(out);
	handles = new HandleTable(10, (float) 3.00);
	subs = new ReplaceTable(10, (float) 3.00);
	enableOverride = false;
	writeStreamHeader();
	bout.setBlockDataMode(true);
        if (extendedDebugInfo) {
	    debugInfoStack = new DebugTraceInfoStack();
	} else {
	    debugInfoStack = null;
        }   
    }


另外,还有从stackoverflow上查到一些socket stream相关的注意事项,挺有用的(对于初学者来说哈):


1-You are using multiple streams over the same socket. Don't do that, they will only confuse each other. As you need object I/O, just use an ObjectInputStream and ObjectOutputStream for everything.--每个socket只有一个ObjectInputStream和一个ObjectOutputStream。

2-Incorrect construction order. You must construct the ObjectOutputStream before the ObjectInputStream, at both ends.--先初始化ObjectOutputStream,再初始化ObjectInputStream。这个问题我也遇到过,所以写到代码的注释中了。不过我试验在服务端不用按照顺序,先初始化哪个都可以。客户端必须按照顺序。

3-You are using streams with different lifetimes. You haven't hit the problem yet but eventually this will lead to a StreamCorruptedException. Use the same ObjectInputStream and ObjectOutputStream for the life of the Socket, at both ends.--socket的生命周期和输入输出流的生命周期应该相同。不要在同一个socket中使用多个输入输出流。实际上又在强调第一点。

今天调这个小例子的感想就是:

1-Slow down。Don't panic。虽然是个简单的小例子。但是之前没用过socket,还有一些输入输出流的类,所以慢点儿是正常的。

2-不要忽略任何一个错误或者异常。


然后我还写了这个例子的进阶版,增加了gui和多线程的应用,具体戳这里:http://blog.csdn.net/alalay168/article/details/9046793



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,你的问题是关于Java socket和PLC通信的。在Java中,可以使用Socket API来实现网络编程,包括与PLC通信。下面是一个简单的Java代码示例,用于向PLC发送数据: ```java import java.io.*; import java.net.*; public class PLCClient { public static void main(String[] args) throws IOException { String hostName = "localhost"; // PLC的IP地址 int portNumber = 12345; // PLC监听的端口号 try (Socket socket = new Socket(hostName, portNumber); PrintWriter out = new PrintWriter(socket.getOutputStream(), true); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in))) { String userInput; while ((userInput = stdIn.readLine()) != null) { out.println(userInput); // 向PLC发送数据 System.out.println("PLC返回的数据:" + in.readLine()); // 读取PLC返回的数据 } } catch (UnknownHostException e) { System.err.println("无法连接到主机:" + hostName); System.exit(1); } catch (IOException e) { System.err.println("无法在端口 " + portNumber + " 上进行连接。"); System.exit(1); } } } ``` 在这个例子中,我们使用了Socket类来建立与PLC的连接,并使用PrintWriter和BufferedReader类来读写数据。当我们向PLC发送数据时,我们可以使用out.println()方法,当我们接收到PLC返回的数据时,我们可以使用in.readLine()方法。 请注意,这只是一个简单的例子,实际上,与PLC通信可能需要使用特定的协议和数据格式。同时需要考虑到网络延迟和数据丢失等问题。因此,如果需要进行生产环境的PLC通信,请务必仔细研究PLC的通信协议和数据格式,以确保数据的正确传输和处理。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值