1
votes

I have sever and client apps, running in IPv6 on Ubuntu1410 default kernel.

Serve: socket listens on loal TCP port and use select() to handle new connections and data;

Client: socket connect the server IPv6 address and port by TCP.

The connection can be successfully established. But, when write() data, buffer size is 128K, it will block in write().

As I need to write many data so i have a for loop to call write(). Sometimes, write() will succeed for one or two times but then it blocks again.

My app supports IPv4 and Ipv6. the write() works on IPv4.

And, if I tested on ::1 (serer and client running on same machine), IPv6 also works.

r = write(fd, buf, buf_size);
2
use wireshark to see what is happening. ipv6 and v4 work so differently that there might be network issues between client and server. - Markus Mikkolainen
Note that IPv6 headers are larger than IPv4 ones, so segmentation of user data will be different over the same MTU. - Nikolai Fetissov
wireshark told me that: after some packet sent by client/ and received by server, also server sent the ACK; then server does not reponse ACK to client for a while. (during this period, client also send PUSH to server). And after a while, it replies ACK to client again, and looks like client stopped doing anything... - Howard Shane
It isn't clear from this which side is doing the sending. Please clarify. - user207421
Sounds to me like this is working as intended. Calls to write() absolutely should block when the client is slow reading and the buffer fills up. It just sounds to me like you haven't properly tested for whether or not this is happening. - Jeremy Visser

2 Answers

1
votes

If a TCP send blocks, the receiver is slow reading.

0
votes

Linux filedescriptors can be set to be nonblocking mode. It can be done either on creation (the open syscall or the socket syscall) or after the fact via the fctl syscall. See the man pages (section 2) for more info.

If a filedescriptor is set to nonblocking mode, an operation on it that would otherwise block will return -1 and set errno to EAGAIN (==EWOULDBLOCK).