[SCTP] nonblocking write()

From: Martin Kulas <coolaz_at_web.de>
Date: Mon, 21 May 2007 00:11:48 +0200
Hello!


I hope this is the right mailing list. I am running -CURRENT and 
I am trying to get an application (thttpd) to use SCTP sockets  
in one-to-one style.

But it does not work.  I tracked the problem down to this:
The SCTP socket is made non-blocking.  Then write() is called.
Write() succeeds if we do not write too many bytes;
net.inet.sctp.sendspace is the limit for an successfull write().

Is this behaviour intended?
Perhaps I am coding something wrong, so here is sample code:

$ nl nb.c
 1	#include <stdio.h>
 2	#include <arpa/inet.h>
 3	#include <netinet/in.h>
 4	#include <sys/types.h>
 5	#include <unistd.h>
 6	#include <sys/socket.h>
 7	#include <err.h>
 8	#include <strings.h>
 9	#include <errno.h>
10	#include <string.h>
11	#include <fcntl.h>
  	
12	#define DST_IP	 "127.0.0.1"
13	#define DST_PORT 1234
  	
14	int
15	main()
16	{
17	    int s;
18	    struct sockaddr_in sa;
19	    int ret;
20	    int n;
21	    char buf[BUFSZ];
22	    int toSend;
  	
23	    printf("BUFSZ: %u\n", BUFSZ);
24	#ifdef USE_SCTP
25	    printf("using sctp\n");
26	    s = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP);
27	#else
28	    printf("using tcp\n");
29	    s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
30	#endif
31	    if ( s == -1 )
32		err(1, "socket() failed");
  	
33	#ifdef USE_NONBLOCKING
34	    printf("using nonblocking i/o\n");
35	    ret = fcntl(s, F_GETFL);
36	    if ( ret == -1 )
37		err(1, "fcntl() failed\n");
38	    ret |= O_NONBLOCK;
39	    ret = fcntl(s, F_SETFL, ret);
40	    if ( ret == -1 )
41		err(1, "fcntl() failed\n");
42	#endif
  	
43	    bzero(&sa, sizeof(sa));
44	    sa.sin_family = AF_INET;
45	    sa.sin_port = htons(DST_PORT);
46	    n = inet_pton(AF_INET, DST_IP, &sa.sin_addr);
47	    if ( n != 1 )
48		err(1, "inet_pton() failed");
  	
49	    ret = connect(s, (struct sockaddr *) &sa, sizeof(sa));
50	    if ( ret == -1 )
51		err(1, "connect() failed");
52	    memset(buf, 'a', BUFSZ);
  	
53	#ifdef USE_WRITE
54	    printf("using write() i/o\n");
55	    toSend = BUFSZ;
56	    while ( toSend > 0 ) {
57		n = write(s, buf, toSend);
58		if ( n > 0 ) {
59		    /* OK */
60		    printf("%d bytes send\n", n);
61		    toSend -= n;
62		} else if ( n == 0 ) {
63		    err(1, "write() EOF (0 bytes written)\n");
64		} else  {
65		    printf("n: %d: %s\n", n, strerror(errno));
66		    sleep(1);
67		}
68	    }
69	#endif
  	
70	    return 0;
71	}


$ cc -Wall -DUSE_SCTP -DUSE_WRITE -DUSE_NONBLOCKING -DBUFSZ=30000 -o nb nb.c 
$ ./nb                                                                      
BUFSZ: 30000
using sctp
using nonblocking i/o
using write() i/o
30000 bytes send
$ cc -Wall -DUSE_SCTP -DUSE_WRITE -DUSE_NONBLOCKING -DBUFSZ=300000 -o nb nb.c
$ ./nb                                                                       
BUFSZ: 300000
using sctp
using nonblocking i/o
using write() i/o
n: -1: Resource temporarily unavailable
n: -1: Resource temporarily unavailable
n: -1: Resource temporarily unavailable
n: -1: Resource temporarily unavailable
n: -1: Resource temporarily unavailable
n: -1: Resource temporarily unavailable
^C


I googled a bit but I do not get any answer if this behaviour is correct 
for non-blocking SCTP socket in one-to-one style.

Thanks in advance,
Martin


-- 
PGP Key: http://www.stud.uni-hamburg.de/~kulas/mkulas_pubkey.asc

Received on Sun May 20 2007 - 20:36:58 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:10 UTC