Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Работа с сетью > Двоекратная посылка данных через сокет


Автор: HugeX 28.6.2010, 13:24
Здравствуйте, дорогие друзья! smile
Я обмениваюсь данными с сервером через SSLSocket. Хотя с клиентом все нормально, как по мне, но посланные мною один раз данные сервер принимает дважды. Никак не пойму, в чем проблема :(
Вот код метода клиента:
Код

    public String sendRequest(String request, boolean waitAnswer) {
        try {
            SSLSocketFactory sslsf = (SSLSocketFactory) SSLSocketFactory.getDefault();
            SSLSocket ssls = (SSLSocket) sslsf.createSocket();
            ssls.connect(new InetSocketAddress("111.111.111.111", 9090), connectTimeOut * 1000);
            ssls.setSoTimeout(readTimeOut * 1000);

            if (waitAnswer) {
                OutputStream os = ssls.getOutputStream();
                InputStream is = ssls.getInputStream();
                os.write(request.getBytes());
                byte[] data = new byte[1024];
                is.read(data);
                is.close();
                os.close();
                ssls.close();
                return new String(data);
            } else {
                OutputStream os = ssls.getOutputStream();
                os.write(request.getBytes());
                os.flush();
                os.close();
                ssls.close();
                return new String("OK");
            }
        } catch(SocketTimeoutException ioe) {
            ioe.printStackTrace();
            return "ERROR";
        } catch(IOException ioe) {
            ioe.printStackTrace();
            return "ERROR";
        }
    }

Кстати, сервер работает на базе NIO Framework. Если кто знает более удачный способ, напишите, пожалуйста. Всем заранее благодарен.

Автор: Skipy 28.6.2010, 15:02
А код сервера можно? Тот, который принимает данные и работает на базе NIO.

Автор: HugeX 28.6.2010, 15:06
Вот код сервера:
Код

package ua.simpletouch.server;

/**
 *
 * @author Alexander Matis
 */
import ch.unifr.nio.framework.AbstractAcceptor;
import ch.unifr.nio.framework.ChannelHandler;
import ch.unifr.nio.framework.Dispatcher;
import ch.unifr.nio.framework.ssl.AbstractSSLChannelHandler;
import ch.unifr.nio.framework.ssl.SSLTools;
import ch.unifr.nio.framework.transform.AbstractForwarder;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.security.GeneralSecurityException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.net.ssl.SSLContext;

public class SSLNIOServer extends AbstractAcceptor {
    private static ExecutorService executor = Executors.newCachedThreadPool();
    private final SSLContext sslContext;

    public SSLNIOServer(Dispatcher dispatcher, SocketAddress socketAddress)
            throws IOException, GeneralSecurityException {
        super(dispatcher, socketAddress);

        URL trustStoreURL = new URL("file:" + Server.getServer().getProperty("storesFolder") + Server.getServer().getProperty("trustStoreServer"));
        URL keyStoreURL = new URL("file:" + Server.getServer().getProperty("storesFolder") + Server.getServer().getProperty("keyStoreServer"));
        sslContext = SSLTools.getServerSSLContext(trustStoreURL, Server.getServer().getProperty("trustStoreServerPass"), keyStoreURL, Server.getServer().getProperty("keyStoreServerPass"), Server.getServer().getProperty("alias"));
    }

    public static void maiN() {
        try {
            Dispatcher dispatcher = new Dispatcher();
            dispatcher.start();

            int port = Integer.parseInt(Server.getServer().getProperty("portToListen"));
            SocketAddress socketAddress = new InetSocketAddress(port);
            SSLNIOServer sSLNIOServer = new SSLNIOServer(dispatcher, socketAddress);
            sSLNIOServer.start();
            
        } catch (GeneralSecurityException gse) {
            gse.printStackTrace();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

    @Override
    protected ChannelHandler getHandler(SocketChannel socketChannel) {
        return new SSLEchoServerChannelHandler(sslContext, socketChannel);
    }

    private static class SSLEchoServerChannelHandler extends AbstractSSLChannelHandler {
        public SSLEchoServerChannelHandler(SSLContext sslContext, SocketChannel socketChannel) {
            super(socketChannel, sslContext, false, 1500, 15000, 1000);

            SSLEchoServerTransformer sslEchoServerTransformer = new SSLEchoServerTransformer();
            sslInputForwarder.setNextForwarder(sslEchoServerTransformer);
            sslEchoServerTransformer.setNextForwarder(byteBufferToArrayForwarder);
        }

        @Override
        public void inputClosed() {
            //System.out.println("SSLEchoClient closed the connection.");
        }

        @Override
        public void channelException(Exception exception) {
            //log.error("Exception", exception);
        }
    }

    private static class SSLEchoServerTransformer extends AbstractForwarder<ByteBuffer, ByteBuffer> {
        @Override
        public void forward(ByteBuffer input) throws IOException {
            executor.execute(new Processing(input, nextForwarder));
        }
    }
}

При поступлении данных вызывается метод forward класса SSLEchoServerTransformer

Автор: HugeX 29.6.2010, 14:11
Решил проблему переходом на Apache MINA smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)