How to configure/reduce tcp segment size - java

I need to send data from my machine to a remote server over tcp and I need the data to be fragmented (it's a test). That explains the reason I am looking for a way to change the segment size to a small number.
I have googled around and I found that we can set MSS using iptables
iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss some-number
However, after more googling, it seems like that solution is used to tell the server the TCP segment size that my machine can accept versus setting the segment size on the tcp packets/segments that my machine is sending over to the server.
I also learnt about MTU and how to change it, but that doesn't seem to be what I want because I need/want to cut my data up in a higher level (in the transport level). My questions are 1) how can I set MSS for TCP segments that my machine is sending? 2) is it possible to do it using Java?
Sorry for these newbie questions.

In C you can do this using by setting the TCP_MAXSEG socket option; see man 7 tcp.
In Java, the relevant socket option is not exposed in the standard Socket APIs. However there is a hint in that page that you might be able to set other options if you implemented a non-standard SocketImpl class.

Just set a small socket send buffer size, if you can.

Related

UNIX UDP Data Transfer with Java

I want to create a UDP OUTPUT=UPLOAD stream using java. I will get my INPUT=SOURCE data from a named pipe or contiguous file opened as a file input stream.
My problem is, ALL of the UDP examples i can find on the internet, only demonstrate console sessions. Echo servers and such.
I'm trying to create a way to stream continuous content such as audio/video, and i don't care what gets lost, i'm leaving that up to my user to be concerned with, however my code does need to allow setting the buffer size, and creating a UDP connection.
Ideally a GOOD example would show how to do upload and download mode connections (client mode and server mode)
Can you provide some code to do this, or show me a link on the internets? The fact that I cannot find a UDP stream client/server example is ridiculous. Using UDP to do console sessions tests the limits of a person's sanity! That should never even be considered optional, let alone useful. The client/server code i need must be compatible with GNU netcat. (to ensure correct performance)
I have tried this with a client:
byte[] buffer = new byte[udpPacketSize]; // 4096
int len;
while ((len = standardInput.read(buffer)) != -1) {
udpSocket.send(new DatagramPacket(buffer, len, host, port));
}
But when I stop sending data, and disconnect, I cannot reconnect to send more data. I'm not sure if that is what is supposed to happen, because 1) I am completely out of my element here and 2) when I disconnect after sending the data, the remote instance of GNU netcat does not exit like it does in TCP mode.
HELP, I need a real network systems engineer, to show me how to implement UDP for practical applications!
[and somebody to remove all of that garbage from the internet, but let's keep it simple]
[further: please do not respond with libraries, packages, or shell commands as a solution. i must be able to execute on any embedded device which may not have the programs, and libraries are not teaching me or anyone else how to do anything on their own.]
But when I stop sending data, and disconnect, I cannot reconnect to send more data.
That's the way GNU Netcat UDP mode works, as far as netcat to netcat on a single machine goes...
Your client needs to read a response from the server before disconnecting. So, while acting as "middle-man", you should not be concerned with this, as long as you can connect your network-client's local-client, to the server's response mechanism.
In other words, you need to provide a bi-directional-half-duplex-connection (1:1 communications), since you are not managing the protocol.
Alternatively, you can use a different UDP server than Gnu Netcat. I have tested this one, and it works without the MUST-READ-REPLY-BUG, effectively meaning, there is nothing wrong with my example code. The must-read-reply feature has nothing to do with a correct UDP server implementation (unless you must connect with a Gnu Netcat 0.7.1 compatible server).
It is worth nothing that it isn't very useful to use Gnu Netcat UDP server mode without a driver (script/program) behind it, especially if you want a continuous process, as you could lock your remote client out of access until the process is respawned.

several TCP-servers on the same port

It looks very strange for me. I can run several TCP servers on the same port.
I use Apache MINA library with following code:
IoAcceptor acceptor = new NioSocketAcceptor();
acceptor.bind(new InetSocketAddress(80));
Port 80 is already used by another program. But I didn't get exception "Address already in use". With netstat I can see following:
C:\>netstat -oan |find /i "LIST"
TCP 0.0.0.0:80 0.0.0.0:0 LISTENING 2220
TCP 0.0.0.0:80 0.0.0.0:0 LISTENING 904
TCP 0.0.0.0:135 0.0.0.0:0 LISTENING 840
Could someone explain me such behaviour?
OS: Windows 7.
Thanks.
Normally only one process can listen on a TCP port, on Windows or any other OS (at least the major ones). On Windows you'd expect to get error code 10048 if two processes share the port. This won't apply if the processes are bound to different interface addresses (even if one is bound to INADDR_ANY and the other is bound to a specific address, they don't clash). Also, this doesn't apply if SO_REUSEADDR has been set on the second socket.
Since both processes are bound to INADDR_ANY and you claim your process hasn't had SO_REUSEADDR set, however, this is a puzzle. As far as I can tell there are three possibilities:
Something in the underlying library is setting SO_REUSEADDR by default.
The second socket was actually opened later and it's the one specifying SO_REUSEADDR.
There is a bug in the Windows sockets layer which allowed this.
I realise no software is perfect, but I really hesitate to choose the third option, especially if you can easily reproduce it. I would suggest carefully watching netstat output before and after starting your process and seeing whether the other listener exists prior to that. Also, try to identify the other process and see whether it's related (you can enable the PID column in the task manager for that).
EDIT
The commenter below has reminded me that I should point out that the behaviour of SO_REUSEADDR does differ across platforms. Windows allows new sockets using the option to forcibly bind to the same port as other listening sockets, with undetermined behaviour if the two sockets are both TCP, as discussed here. In practice the second socket probably "steals" the address, but the official line seems to be that the behaviour is undefined:
Once the second socket has successfully bound, the behavior for all sockets bound to that port is indeterminate. For example, if all of the sockets on the same port provide TCP service, any incoming TCP connection requests over the port cannot be guaranteed to be handled by the correct socket — the behavior is non-deterministic.
Linux (and other Unix variants) will not allow two TCP sockets to share the same port if the old one is still listening. In this case, SO_REUSEADDR only allows the new socket to bind if the old one is in TIME_WAIT (and perhaps the FIN_WAIT and CLOSE_WAIT states, I'd have to check that).
As an aside, I found the difference in behaviour quite surprising when I first came across it in Windows, but I've tested it myself and certainly if you set SO_REUSEADDR on both sockets it's quite possibly to bind successfully to exactly the same address and port simultaneously. I haven't done extensive testing on the exact behaviour in this situation, however, since in my case it didn't matter too much.
I'm not about to get into which platform is "correct", but certainly the Windows behaviour has lead to security issues which is why they came up with the SO_EXCLUSIVEADDRUSE option to prevent other sockets forcibly binding. I've also seem people of the opinion that the Windows version should be regarded as a completely different option, with different behaviour, which just happens to have the same name.

Is one port for read, one port for write a good idea for socket applications?

I am wondering if it is a good idea to have 2 separate ports one for read, one for write ? Can I expect better performance ?
NOTE: Server is Centos, Client is flash, message format in communication is JSON.
There's no significant performance advantage, and it can require much more code to handle two sockets than one, particularly on the server side.
You'd also still have to open both sockets from the client side, as most systems wouldn't permit the server to open a connection back to the client.
AFAIK, TCP is optimised assuming you will send a request and get a response on the same socket, however the difference is likely to be trivial.
Often the simplest solution is also the fastest.
What is the problem you are trying to solve?
Best to have it in TCP with a single port, also depending if you are using NIO or not,
Just in case you want to have 2 ports & Unless its not a TCP (eg UDP)
If you are in Cent OS 32 bit, ensure that your kernel to use up more ports that it should.
This is to prevent port starvation & would quickly cripple your server.
Do the math, if you need to support 100 users, 100 x 2 = 200 open ports.
but in most cases, its only (65534 - 1024) ports available, so, if you could afford it, then its cool.
Also remember that most ISP's would block certain ports, so keep the right ports open for read / write.
regards

Java sockets and TCP tuning

I try to develop a file transfer application in Java, with an applet as client, and a standalone java app as server (on a dedicated machine hosted in a datacenter).
I use DataOutputStream/DataInputStream to transfers the data on both sides.
When I send big volumes of data, the bandwith is very variable : all is okay first, then the tcp stream is freezed during 40-50 seconds while nothing is transferring, and then it starts again.
When I look at the tcp stream with Ethereal, I see duplicate acks, fast retransmits, and tcp retransmits.
But I don't think that the problem is originating from Java : I have the same problem with FTP transfers in FileZilla.
But ... when I try to transfer data using netcat (netcat client + netcat server), all is fine, the bandwith is stable, the tcp lost packets seems to be retransmitted immediately without any pause, no matter of the volume transferred.
It's like if Java was not as talented as netcat to play with tcp streams ...
I tried to play with Socket.setSendBufferSize(), but I didn't see any difference.
Any idea ?
Thanks !
And sorry for my bad english ...
Mr amischiefr is right !
It's the same problem that on the other thread.
My problem was solved by replacing DataXXXputStream by BufferedXXXputstream.
The write(byte[], off, len) methods are the same, and the doc doesn't talk about such different behavior. DataOutputStream is buffered, BufferedOutputStream too, but the second one does it much better.
Thanks !
Sounds more like your network is bogged down and you are seeing TCP windowing (I believe that's the correct term) basically limiting your bandwidth.

Java TCP Socket Sniffing

I am using TCP sockets to communicate data between a server and client program using a specific port number on the same computer (localhost).
I need a software that can capture the data being sent/received through that socket?
(or)
What's the simplest way of sniffing packets from a specified port in Java?
I suggest using Wireshark. It's easy to use and runs on many platforms.
http://www.wireshark.org/
If you are up to some coding (and not just running the wireshark/tcpdump) then you have few choices. If you want stick to Java, then the only (?) option to use raw sockets is via JNI and there are few libraries that can help, for example:
jNetPcap - wrapper around the native libpcap/winpcap libraries, exposing all of their functions and structures
RockSaw - API for using raw sockets
The easiest way is to replace the InputStream/OutputStream from a socket in one of the programs with a proxy implementation, that either prints/logs or "tees" to the original and a print/log stream.
But there's plenty of sniffers out there if you really want to get messy.
If you don't mind getting down and dirty with the command line you could try netcat.
It'll let you listen on a port and dump the output to a file if you like.
You can also make it send fake data and record the response.
I often use it as a pretend HTTP proxy (and configure Firefox to use it) to discover what is being sent over the wire.
Tcpdump can also be used directly, if the volume of traffic is not high, obviating the need to use wireshark. Just something like
tcpdump -ni lo0 port 1234
should be all you need (lo0 is the loopback interface on all Unix/Linux systems; also change the port number of course).
Run your program like so:
java -Djavax.net.debug=all helloworld.java
The switch is fully documented on the Oracle JSSE page
Pros:
Much simpler than other suggested solutions (requires no external software)
Can also decrypt/dump TLS/SSL connections :)
Cons:
This will only work if you are using classes from java.net.* e.g. OutputStream or InputStream This will not work if you're using raw sockets. This is documented in the link.
Believe this may only work on the Oracle JDK.
You can use tcpdump that gives you a variety of options. You save the capture in a .pcap file with the -w option and when you are done you open that file with wireshark. The advantage of this way is that you can capture a high rate of packets per second without affecting the overall performance of your pc (even if it is low end).

Categories