# TCP Connection zu langsam



## Thalion (22. Apr 2015)

Guten Tag,
ich wollte einmal Anfragen, ob jemand eine Lösung für mein Problem hätte.
Ich arbeite zur Zeit an einem kleinen Netzwerkcode, jedoch habe ich bemerkt, dass für meine Verwendungszwecke eine größere Lese-/Schreibgeschwindigkeit benötigt wird. Ich habe einige Lektüre zu NIO-Channeln, Selector und Buffern durchgearbeitet, jedoch selbst mit Verbesserung kam keine deutliche Leistungssteigerung zusammen.

Der jetzige Code schafft hochgerechnet ca. 1KB/s ( Ziel wären 5-6 MB/s ).
IDE: Eclipse Luna x64
CPU: Intel Core i7 3770K
RAM: 4x 4GB Kingston Hyperserie
Netzwerktreiber: Atheros Qualcomm Killer Network Manager ( müsste so stimmen )

Server:

```
import java.io.IOException;import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;




public class MainClass {
    
    private static ServerSocketChannel ssc;
    
    private static Selector selector;
    
    private static Thread[] threads = new Thread[2];


    public static void main(String[] args) throws IOException {
        init();
        selector = Selector.open();
        Thread thread;
        thread = genComThread();
        thread.start();
    }
    
    private static Thread genComThread() {
        return new Thread(new Runnable() {


            @Override
            public void run() {
                while(true) {
                    
                    try {
                        
                        SocketChannel sc;
                        if((sc = ssc.accept()) != null) {
                            sc.configureBlocking(false);
                            sc.register(selector, (SelectionKey.OP_READ | SelectionKey.OP_WRITE));
                        }
                        
                        if(selector.selectNow() > 0) {
                            processChannel(selector.selectedKeys());
                        }
                        
                        
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                    
                    try {
                        Thread.sleep(0L, 1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    
                }
            }


            private void processChannel(Set<SelectionKey> selectedKeys) throws Exception {
                Iterator<SelectionKey> iterator = selectedKeys.iterator();
                
                SelectionKey sk;
                SocketChannel sc;
                while(iterator.hasNext()) {
                    
                    sk = iterator.next();
                    if(sk.isReadable()) {
                        sc = (SocketChannel) sk.channel();
                        ByteBuffer buffer = ByteBuffer.allocate(1024);
                        
                        try {
                            System.out.print("N: " + sc.read(buffer));
                            System.out.println(" | String: " + new String(buffer.array()));
                        } catch (Exception ex) {
                            sk.cancel();
                            ex.printStackTrace();
                        }
                    }
                    
//                    iterator.remove();
                }
            }
            
        });
    }
    
    private static void init() throws IOException {
        ssc = ServerSocketChannel.open();
        ssc.bind(new InetSocketAddress("127.0.0.1", 55555));
        ssc.configureBlocking(false);
    }


}
```

Client:

```
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.Calendar;




public class CMainClass {
    
    private static SocketChannel sc;


    public static void main(String[] args) throws Exception {
        init();
        
        StringBuilder sb = new StringBuilder(Calendar.getInstance().getTime() + " | ");
        for(int i = 0; i < 1024; i ++) {
            sb.append(String.valueOf(i).substring(0, 1));
        }
        
        ByteBuffer buffer;
        buffer = ByteBuffer.allocate(sb.length());
        buffer.put(sb.toString().getBytes());
        
        buffer.flip();
        
        sc.configureBlocking(false);
        
        long t = System.nanoTime();
        while(buffer.hasRemaining()) {
            System.out.println("Write ...");
            sc.write(buffer);
        }
        System.out.println(System.nanoTime() - t + " nanos");
        
        buffer.clear();
        while(sc.read(buffer) < 1)
            Thread.sleep(0L, 1);
        System.out.println(new String(buffer.array()));
        
    }
    
    private static void init() throws Exception {
        sc = SocketChannel.open();
        sc.connect(new InetSocketAddress("127.0.0.1", 55555));
    }


}
```

Vielen Dank schon im voraus.

Mit freundlichen Grüßen,
Thalion


----------



## Tobse (22. Apr 2015)

1KB/s über TCP? Dann machst du was falsch. An guten Internetleitungen bekommst du mit TCP Downstreams von 8 - 10 MB/s problemlos hin. Deine Verbindung geht über localhost/127.0.0.1; da müsste noch sehr viel mehr drin sein. Du machst eindeutig was falsch 

Such mal nach Performance-blockern. Irgendwo wartest du ggf. o.ä. Vllt ist auch einfach deine Messung mit 1KB/s falsch.


----------



## Thalion (23. Apr 2015)

Ok, habe das Problem gefixt bekommen.
Der ganze Fehler lag bei der größe des Buffers zum Lesen/Schreiben.
Mit kleinem Umgeschriebenem Code gehen jetzt ca. 12MB in 0.6s


```
import java.io.IOException;import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;




public class MainClass {
	
	private static ServerSocketChannel ssc;
	
	private static Selector selector;
	
	private static Thread[] threads = new Thread[2];


	public static void main(String[] args) throws IOException {
		init();
		selector = Selector.open();
		Thread thread;
		thread = genComThread();
		thread.start();
	}
	
	private static Thread genComThread() {
		return new Thread(new Runnable() {


			@Override
			public void run() {
				while(true) {
					
					try {
						
						SocketChannel sc;
						if((sc = ssc.accept()) != null) {
							sc.configureBlocking(false);
							sc.register(selector, (SelectionKey.OP_READ | SelectionKey.OP_WRITE));
						}
						
						if(selector.selectNow() > 0) {
							processChannel(selector.selectedKeys());
						}
						
						
					} catch (Exception ex) {
						ex.printStackTrace();
					}
					
					try {
						Thread.sleep(0L, 1);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					
				}
			}


			private void processChannel(Set<SelectionKey> selectedKeys) throws Exception {
				Iterator<SelectionKey> iterator = selectedKeys.iterator();
				
				SelectionKey sk;
				SocketChannel sc;
				while(iterator.hasNext()) {
					
					sk = iterator.next();
					if(sk.isReadable()) {
						sc = (SocketChannel) sk.channel();
						ByteBuffer buffer = ByteBuffer.allocate(32768);
						
						try {
							sc.read(buffer);
//							System.out.print("N: " + sc.read(buffer));
//							System.out.println(" | String: " + new String(buffer.array()));
						} catch (Exception ex) {
							sk.cancel();
							ex.printStackTrace();
						}
					}
					
//					iterator.remove();
				}
			}
			
		});
	}
	
	private static void init() throws IOException {
		ssc = ServerSocketChannel.open();
		ssc.bind(new InetSocketAddress("127.0.0.1", 55555));
		ssc.configureBlocking(false);
	}


}
```


```
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.Calendar;




public class CMainClass {
	
	private static SocketChannel sc;


	public static void main(String[] args) throws Exception {
		init();
		
		ByteBuffer[] buffers = new ByteBuffer[384];
		
		StringBuilder sb = new StringBuilder(Calendar.getInstance().getTime() + " | ");
		for(int i = 0; i < 32736; i ++) {
			sb.append(String.valueOf(i).substring(0, 1));
		}
		
		for(int i = 0; i < 384; i ++) {
			ByteBuffer buffer;
			buffer = ByteBuffer.allocate(sb.length());
			buffer.put(sb.toString().getBytes());
			
			buffer.flip();
			buffers[i]  = buffer;
		}
		
		sc.configureBlocking(false);
		
		long t = System.currentTimeMillis();
		for(ByteBuffer buffer : buffers) {
			while(buffer.hasRemaining()) {
				sc.write(buffer);
			}
		}
		System.out.println(System.currentTimeMillis() - t + " millis");
		
		ByteBuffer buffer = ByteBuffer.allocate(1024);
		buffer.clear();
		while(sc.read(buffer) < 1)
			Thread.sleep(0L, 1);
		System.out.println(new String(buffer.array()));
		
	}
	
	private static void init() throws Exception {
		sc = SocketChannel.open();
		sc.connect(new InetSocketAddress("127.0.0.1", 55555));
	}


}
```


----------

