Closed caozhiyuan closed 4 years ago
Server in Windows and Client in Ubuntu
when send wouldblock,it has sent some bytes
@caozhiyuan TCP is a 'stream' protocol. This means data sent in 1 operation by one peer, can arrive at the other peer in separate messages. It looks like you are observing a message being cut because it would go over the peer recv buffer size. Then you hit the WouldBlock on the next send because the OS is waiting for the peer to receive data.
I made a repro without DotNetty
Socket.Send returns 0, but 29200 bytes are transmited in network. (NonBlocking mode is enabled)
To Run test
Depoloy TestTCP on Ubuntu14.04
1.1 Build
1.2 Copy files
1.3 Enable connections to port 8183 ( ufw allow 8183)
1.4 Start listener ( dotnet TestTCP.dll syncnoblock
)
On Windows (client) side
2.1 dotnet TestTCP get __your_ubuntu_ip_address
TestTCPSyncNoBlock.zip origin from https://github.com/Azure/DotNetty/issues/286
@tmds @IvanAntipov linux it always returns 0, 0 means no buffer send. in windows no this problem(29200 bytes are transmited in network)
@IvanAntipov please share the console output of client&server when running the steps.
@tmds
please share the console output of client&server when running the steps.
@IvanAntipov both in windows , no this problem. now in linux ,I set socket blocking to true , dotnetty works ok.
@IvanAntipov Interesting. Can you share the output when running strace -f -e sendmsg dotnet TestTCP.dll syncnoblock
?
@tmds
Can you share the output when running strace -f -e sendmsg dotnet TestTCP.dll syncnoblock?
root@test9:/usr/src/testtcp# strace -f -e sendmsg dotnet TestTCP.dll syncnoblockProcess 16245 attached Process 16244 attached Process 16246 attached Process 16247 attached Process 16248 attached Process 16249 attached ListenSyncSendNoBlock Process 16250 attached Process 16251 attached Bind Wait Process 16252 attached [pid 16251] +++ exited with 0 +++ Process 16253 attached Send Process 16254 attached [pid 16250] sendmsg(33, {msg_name(0)=NULL, msg_iov(1)=[{"<!DOCTYPE html>\r\n<html class=\" a"..., 127135}], msg_controllen=0, msg_flags=0}, 0) = 29200 [pid 16250] sendmsg(33, {msg_name(0)=NULL, msg_iov(1)=[{"pan class=\"x-phlinktext\">\320\230\320"..., 97935}], msg_controllen=0, msg_flags=0}, 0) = -1 EAGAIN (Resource temporarily unavailable) Sent count 0 Wait [pid 16253] +++ exited with 0 +++ [pid 16254] +++ exited with 0 +++ [pid 16250] +++ exited with 0 +++
@IvanAntipov Send
should have returned 29200
(return value from first sendmsg call). Are you running .NET Core 2.0 release on the Linux machine?
@tmds
Send should have returned 29200 (return value from first sendmsg call). Are you running .NET Core 2.0 release on the Linux machine?
Yes, I running .Net Core 2.0 on Linux (Ubuntu 14.04). It should, but it doesnt :)
I think we arrive here: https://github.com/dotnet/corefx/blob/fe0e443ac01ee5a5afefb302b89f1504c3988eda/src/System.Net.Sockets/src/System/Net/Sockets/Socket.cs#L1210-L1220
errorCode is WouldBlock and 0
is returned instead of bytesTransferred
.
Summary:
Socket.Send returns 0
instead of the amount of bytes transferred when data is partially sent over a non-blocking socket.
\cc @stephentoub @geoffkizer @karelz
Minimal repro:
var listener = new TcpListener(IPAddress.Loopback, 0);
listener.Start();
var client = new TcpClient();
client.Connect(listener.LocalEndpoint as IPEndPoint);
Socket socket = listener.AcceptSocket();
socket.Blocking = false;
var data = new byte[100_000_000];
SocketError error;
int bytesSent = socket.Send(data, 0, data.Length, SocketFlags.None, out error);
Console.WriteLine($"{bytesSent} - {error}");
outputs:
0 - WouldBlock
strace shows:
sendmsg(26, {msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., iov_len=100000000}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 2772174
sendmsg(26, {msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., iov_len=97227826}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = -1 EAGAIN (Resource temporarily unavailable)
The output should have been:
2772174 - Success
@tmds @stephentoub is has any idea when to fix it, we need use it online
@tmds wo now use Socket.SendAsync(operation) , async method no bug
@caozhiyuan that is the preferred way of working: :+1:
https://github.com/caozhiyuan/DotNetty/tree/dev/examples/SocketAsyncClient
https://github.com/caozhiyuan/DotNetty/tree/dev/examples/SocketAsyncServer
[EDIT] Add C# syntax highlighting by @karelz