在java中的单个套接字上读写

时间:2018-04-17 15:20:22

标签: java spring sockets serversocket

我有一个套接字服务器,它只接受一个客户端套接字连接。它会记住连接并发送响应。如果客户端再次打开与服务器相同的主机和端口的连接,则服务器将接受它,但在最后记住的套接字连接上发送响应。我不知道服务器是如何做到的,因为它不在我的掌控之中。

下面是我试过的代码。在我的代码中,我首先创建与服务器的Socket连接并将其存储在Spring应用程序上下文中。对于每个请求,我都会得到它并使用输入和输出流。

我能够发送一个请求并收到一个响应。但是当我发送第二个请求时,我没有得到服务器的任何响应。

请注意,服务器以前两个字节发送消息长度并附加其余的响应。

对于第二个回复,我的标题为0000,响应为null

有人可以指出我的例子,客户端只创建一个带服务器的套接字,并为每个请求使用其输入和输出流。下面是我试过的代码。

SocketConnector.java

public class SocketConnector {

    LoggerUtil log = LoggerUtil.getInstance();
    final String className = "SocketConnector";

    @Value("${socket.host}")
    String socketHost;

    @Value("${socket.port}")
    int socketPort;

    @Value("${socket.connection.timeout}")
    int socketConnectionTimeout;

    @Value("${socket.read.timeout}")
    int socketReadTimeout;

    @Bean
    Socket socketSocket(){
        Socket s = new Socket();
        final String methodName = "socketSocket";
        try {
            s.connect(new InetSocketAddress(socketHost, socketPort), socketConnectionTimeout); // Connection timeout set to 5 seconds with socket.
            s.setSoTimeout(socketReadTimeout); // Read timeout set to 2 seconds. This means socket should send response in maximum of 2 second for every request.
            log.doLog(3, className, methodName, "Created Socket Connection");
        } catch (IOException e) {
            log.doLog(3, className, methodName, LoggerUtil.getExStackTrace(e));
        } 
        return s;
    };
}

LogonScheduler.java

@Configuration
@EnableScheduling
public class LogonScheduler {

    @Autowired
    @Qualifier("socketSocket")
    private Socket socketSocket;

    private DataInputStream socketInputStream;
    private OutputStream socketOutputStream;

    static LoggerUtil log = LoggerUtil.getInstance();

    final static String className = "LogonScheduler";
    String logonResponse = null;

    byte[] reqMsg = null;
    byte[] msgLen = null;
    byte[] header = null;
    byte[] buf = null;
    byte[] response = null;

    int messageLen = -1;

    /*@Scheduled(fixedDelay = 17500)*/
    @Scheduled(fixedDelay = 10000)
    public void logonSender(){
        final String methodName = "logonSender";
        try {
            socketInputStream = new DataInputStream(socketSocket.getInputStream());
            socketOutputStream = socketSocket.getOutputStream();

            /*
            * Created a byte array named buf and writing to socketOutputStream
            * buf = createRequest();
            */

            socketOutputStream.write(buf);

            header = new byte[2];
            socketInputStream.read(header, 0, 2);

            messageLen = Integer.parseInt(bytetoHex(header), 16);
            log.doLog(4, className, methodName, "Message length received :" + messageLen);

            logonResponse = bytetoHex(header);
            response = new byte[messageLen];
            socketInputStream.readFully(response, 0, messageLen);

            logonResponse += bytetoHex(response);

            log.doLog(4, className, methodName, "Response Message with header : " + logonResponse);
            logonResponse = logonResponse.substring(4);
            log.doLog(4, className, methodName, "Response Message without header : " + logonResponse);

        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            Utils.closeResources(logonResponse, reqMsg, msgLen, header, buf, response, messageLen);
        }
    }

    public String bytetoHex(byte[] b) {
        if (isEmpty(b)) {
            return null;
        }

        String hex = "";
        for (int i = 0; i < b.length; i++) {
            hex += byteToHex(b[i]);
        }

        return hex;
    }

    // Returns hex String representation of byte b
    public String byteToHex(byte b) {
        char[] array = {hexDigit[(b >> 4) & 0x0f], hexDigit[b & 0x0f]};
        return new String(array);
    }
}

0 个答案:

没有答案