I am use Netty ( a java network framework) to server UDP request .
I found the
SO_RCVBUF
and
/proc/sys/net/core/rmem_default
and
/proc/net/udp
output confusing:
By the manual of socket( man 7 socket) It explains :
rmem_default
contains the default setting in bytes of the socket receive
buffer.
rmem_max
contains the maximum socket receive buffer size in bytes which
a user may set by using the SO_RCVBUF socket option.
and the /proc/net/udp show's the udp receive queue size :
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
60: 00000000:2F3C 00000000:0000 07 00000000:0003E094 00:00000000 00000000 500 0 2224362 2 ffff810066908cc0
I can get the SO_RCVBUF = 12904, but the rx_queue size is 254100(3E094), and rmem_default is 262142
my confuse is, why the SO_RCVBUF not equals to the rmem_default, and why the queue size not equals the SO_RCVBUF (but larger than it ) ?
It seams the ctx.channel().config().getOption(ChannelOption.SO_RCVBUF)'s value is half of /proc/sys/net/core/rmem_default and the real receive buffer size( queue size ) is also the value of /proc/sys/net/core/rmem_default
so why ctx.channel().config().getOption(ChannelOption.SO_RCVBUF) not equals to the system's config ?
The accepted answer is wrong. The correct alignment is:
tx_queue rx_queue
00000000:0003E094
So rx_queue is 0x0003E094 or 254100. This can be confirmed using netstat -unlp | grep pid , Recv-Q is second column. Example output:
cat /proc/net/udp
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode ref pointer drops
8101: 41FD080A:06A5 00000000:0000 07 00000000:00005A00 00:00000000 00000000 1000 0 3892411 2 0000000000000000 0
netstat --udp -nl
Proto Recv-Q Send-Q Local Address Foreign Address State
udp 23040 0 10.8.253.65:1701 0.0.0.0:*
Here, 0x00005A00==23040
You seem to have misread the output. When you line up the columns properly, rx_queue is zero.
Related
Two parts:
InetAddress ia = Inet4Address.getByAddress(new byte[]{(byte)192,(byte)168,(byte)10,(byte)100});
Socket socket = new Socket();
InetSocketAddress isa = new InetSocketAddress("82.146.58.81", 5277);
socket.bind(new InetSocketAddress(ia, 0));
System.out.println("local_address:" + socket.getLocalSocketAddress());
socket.connect(isa, 1000);
Thread.sleep(1000);
socket.close();
System.out.println("done_1");
InetAddress ia_2 = Inet4Address.getByAddress(new byte[]{(byte)172,(byte)20,(byte)10,(byte)2});
Socket socket_2 = new Socket();
InetSocketAddress isa2 = new InetSocketAddress("82.146.58.81", 5277);
socket_2.bind(new InetSocketAddress(ia_2, 0));
System.out.println("local_address:" + socket_2.getLocalSocketAddress());
socket_2.connect(isa2, 30000);
Thread.sleep(1000);
socket_2.close();
System.out.println("done_2");
First part of code worked, second not - java.net.SocketTimeoutException: connect timed out.
I am trying to communicate with the host "82.146.58.81" through different interfaces.
But only the part that has the default route is successful. Why?
Update: I am worked by Ubuntu 17.10, seems the same problem in Armbian too. Problem not reproducible under Windows7
Update: Wrong OUT interface:
[12979.049742] IN= OUT=enp4s0 SRC=172.20.10.2 DST=82.146.58.81 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=25967 DF PROTO=TCP SPT=48985 DPT=5277 WINDOW=29200 RES=0x00 SYN URGP=0
kostas#work:~$ ifconfig
enp0s16f0u1c4i2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.20.10.2 netmask 255.255.255.240 broadcast 172.20.10.15
inet6 fe80::17c7:4582:897b:11d5 prefixlen 64 scopeid 0x20<link>
ether 86:38:35:c8:f5:39 txqueuelen 1000 (Ethernet)
RX packets 575 bytes 117085 (117.0 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 686 bytes 82681 (82.6 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
enp4s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.10.100 netmask 255.255.255.0 broadcast 192.168.10.255
inet6 fe80::80b9:8cf3:92c6:4aef prefixlen 64 scopeid 0x20<link>
ether 00:e0:66:ae:2a:de txqueuelen 1000 (Ethernet)
RX packets 100455 bytes 65543315 (65.5 MB)
RX errors 0 dropped 1 overruns 0 frame 0
TX packets 75513 bytes 15658830 (15.6 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
kostas#work:~$ route
Таблица маршутизации ядра протокола IP
Destination Gateway Genmask Flags Metric Ref Use Iface
default unknown 0.0.0.0 UG 100 0 0 enp4s0
default gateway 0.0.0.0 UG 101 0 0 enp0s16f0u1c4i2
kostas#work:~$ ping mail.ru -I enp0s16f0u1c4i2
PING mail.ru (217.69.139.202) from 172.20.10.2 enp0s16f0u1c4i2: 56(84) bytes of data.
64 bytes from mail.ru (217.69.139.202): icmp_seq=1 ttl=51 time=508 ms
64 bytes from mail.ru (217.69.139.202): icmp_seq=2 ttl=51 time=187 ms
"However, many OSes do not honour this "hint" and will use the routing table anyway."
Answer here
In my java server Application, 1000 UDP packets are coming per second. But my application can process only 100 packets/sec. So there are like 900 UDP packets/sec that my server can not process.
The server application is doing something like this.
while(true)
{
serverSocket.receive(receivePacket);
process(receivePacket); // takes around 50ms to complete
serverSocket.send(sendPacket);
}
From my understanding, those unprocessed packets are getting stored in OS's UDP receive buffer. when this buffer will become full OS will drop those packets.
But the problem is when I run the command to see my UDP buffer size.
cat /proc/net/udp
It shows that there is nothing stored on my UDP socket buffer
cat /proc/net/udp
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode ref pointer drops
4: FCA9C11F:C36F 8C719AC6:0035 01 00000000:00000000 00:00000000 00000000 0 0 2983494501 2 ffff880169aff4c0 0
5: FCA9C11F:D3F0 8C719AC6:0035 01 00000000:00000000 00:00000000 00000000 0 0 2983494485 2 ffff8801b9bbedc0 0
16: 7A52BB59:007B 00000000:0000 07 00000000:00000000 00:00000000 00000000 38 0 2438608536 2 ffff8807656764c0 0
16: A2EE0D55:007B 00000000:0000 07 00000000:00000000 00:00000000 00000000 38 0 2438608045 2 ffff88077ccdd7c0 0
16: A58F466D:007B 00000000:0000 07 00000000:00000000 00:00000000 00000000 38 0 2438607809 2 ffff8801129f6240 0
It shows there is no packet drop and tx_queue and rx_queue are 0 in size. So there are no packets stored in UDP receive buffer?
But if I take a tcpdump, then I can see that lots of packets a coming to the server and server can process only 10% all those packets. so the other 90% should be stored in the UDP receive buffer.
What am i missing or not understanding?
I made an android application that returns to the console some Linux commands.
In this case I want to find my wlan0 ip and my wlan1(when is connected) ip.
I've got the full text returned by ifconfig command. The problem is how can get into 2 variables these 2 IPs?
I Tried to substring after inet word but there are more than 1 word with inet. What is the optimal solution for this?
This is my string :
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 16436
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 0 (Local Loopback)
RX packets 37 bytes 7123 (6.9 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 37 bytes 7123 (6.9 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
p2p0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet6 xxxxxx prefixlen 64 scopeid 0x20<link>
ether xxxxxx txqueuelen 1000 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.0.100 netmask 255.255.255.0 broadcast 192.168.0.255
inet6 xxxxxxxxxxx prefixlen 64 scopeid 0x20<link>
ether xxxxxxx6 txqueuelen 1000 (Ethernet)
RX packets 1504 bytes 817297 (798.1 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 686 bytes 126080 (123.1 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
Please note that I don't care about :p2p0 or lo section, only wlan0 and wlan1(when is connected).
What I want is to save 192.168.0.100 into a String ip;
Thanks in advance!
I am not sure if i understood what you trying but i think Regular Expressions
is a possible way to go
I have a java app program run on centos 6.3 and tomcat 7 as the app container, currently I meet one error : java.io.socketexception Maximum number of datagram sockets reached
we use MulticastSocket class to send message. when this error happened, I check the current server UDP socket count with command: ss -s
Total: 212 (kernel 248)
TCP: 70 (estab 15, closed 44, orphaned 0, synrecv 0, timewait 40/0), ports 22
Transport Total IP IPv6
* 248 - -
RAW 0 0 0
UDP 40 40 0
TCP 26 26 0
INET 66 66 0
FRAG 0 0 0
and I also check the
ulimits -n
The default setting is 32768, seem UDP socket count not exceed max count.
Any ideas for this error?
we use MulticastSocket class to send message.
Why? You only need a MulticastSocket to receive multicasts.
Obviously you are leaking MulticastSockets. Presumably you are creating a new one per message and never closing it.
I'm new to Scala so the question may be quite simple, though I have spent some time trying to resolve it. I have a simple Scala TCP server (no actors, single thread):
import java.io._
import java.net._
object Application {
def readSocket(socket: Socket): String = {
val bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream))
var request = ""
var line = ""
do {
line = bufferedReader.readLine()
if (line == null) {
println("Stream terminated")
return request
}
request += line + "\n"
} while (line != "")
request
}
def writeSocket(socket: Socket, string: String) {
val out: PrintWriter = new PrintWriter(new OutputStreamWriter(socket.getOutputStream))
out.println(string)
out.flush()
}
def main(args: Array[String]) {
val port = 8000
val serverSocket = new ServerSocket(port)
while (true) {
val socket = serverSocket.accept()
readSocket(socket)
writeSocket(socket, "HTTP/1.1 200 OK\r\n\r\nOK")
socket.close()
}
}
}
The server listens on localhost:8000 for incomming requests and sends HTTP response with single OK word in the body. Then I run Apache Benchmark like this:
ab -c 1000 -n 10000 http://localhost:8000/
which works nicely for the first time. The second time I start ab it hangs producing the following output in netstat -a | grep 8000:
....
tcp 0 0 localhost.localdo:43709 localhost.localdom:8000 FIN_WAIT2
tcp 0 0 localhost.localdo:43711 localhost.localdom:8000 FIN_WAIT2
tcp 0 0 localhost.localdo:43717 localhost.localdom:8000 FIN_WAIT2
tcp 0 0 localhost.localdo:43777 localhost.localdom:8000 FIN_WAIT2
tcp 0 0 localhost.localdo:43722 localhost.localdom:8000 FIN_WAIT2
tcp 0 0 localhost.localdo:43725 localhost.localdom:8000 FIN_WAIT2
tcp6 0 0 [::]:8000 [::]:* LISTEN
tcp6 83 0 localhost.localdom:8000 localhost.localdo:43724 CLOSE_WAIT
tcp6 83 0 localhost.localdom:8000 localhost.localdo:43786 CLOSE_WAIT
tcp6 1 0 localhost.localdom:8000 localhost.localdo:43679 CLOSE_WAIT
tcp6 83 0 localhost.localdom:8000 localhost.localdo:43735 CLOSE_WAIT
tcp6 83 0 localhost.localdom:8000 localhost.localdo:43757 CLOSE_WAIT
tcp6 83 0 localhost.localdom:8000 localhost.localdo:43754 CLOSE_WAIT
tcp6 83 0 localhost.localdom:8000 localhost.localdo:43723 CLOSE_WAIT
....
Since that no more requests are served by the server. One more detail: The same ab script with the same parameters works smoothly testing a simple Node.js server on the same machine. So this issue is not related to a number of opened TCP connections which I have set to be reusable with
sudo sysctl -w net.ipv4.tcp_tw_recycle=1
sudo sysctl -w net.ipv4.tcp_tw_reuse=1
Could anyone give me a clue on what I'm missing?
Edit: Termination of stream handling has been added to the code above:
if (line == null) {
println("Stream terminated")
return request
}
I'm posting the (partial) answer to my own question for those who will stumble upon the same issue one day. First, the nature of the problem lies not in the source code but in the system itself which restricts numerious connections. The problem is that the socket passed to readSocket function appears corrupted under some conditions, i.e. it can not be read and bufferedReader.readLine() either returns null on first call or hangs indefinitely. The following two steps make the code working on some machines:
Increase the number of concurrent connections to a socket with
sysctl -w net.core.somaxconn=65535
Provide the second parameter to ServerSocket constructor which will explicitly set the length of connection queue:
val maxQueue = 50000
val serverSocket = new ServerSocket(port, maxQueue)
The steps above solve the problem on EC2 m1.large instances, however I'm still getting issues on my local machine. The better way would be to use Akka for the stuff of that kind:
import akka.actor._
import java.net.InetSocketAddress
import akka.util.ByteString
class TCPServer(port: Int) extends Actor {
override def preStart {
IOManager(context.system).listen(new InetSocketAddress(port))
}
def receive = {
case IO.NewClient(server) =>
server.accept()
case IO.Read(rHandle, bytes) => {
val byteString = ByteString("HTTP/1.1 200 OK\r\n\r\nOK")
rHandle.asSocket.write(byteString)
rHandle.close()
}
}
}
object Application {
def main(args: Array[String]) {
val port = 8000
ActorSystem().actorOf(Props(new TCPServer(port)))
}
}
First, I'd suggest trying this without ab. You can do something like:
echo "I'm\nHappy\n" | nc -vv localhost 8000
Second, I'd suggest handling end-of-stream. This is where BufferedReader.readLine() returns null. The code above only checks for an empty String. After you fix this, I'd try again. Then test with ab, after everything looks good. Let us know if the problem persists.