This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: VM and non-blocking writes


Okay, here's my test program.  Compile and run with no arguments, then
connect to it from another machine - on a linux box I just did:

python
import socket
s = socket.socket()
s.connect(("name-of-windows-box", 12345))

At this point, nbcheck printed:

listening to port 12345 on host xp1 (10.1.2.40)
got connection from 10.1.2.14
trying to write 100000000
100000000 bytes written

When I hit return to exit from nbcheck, it does not actually exit until
the remote socket is closed.

The VM usage is 100M, which is all the data array that I allocated, so
it doesn't look like the write() call allocated anything in my process
space.

This behavior makes some sense to me, but it's not how I expect it to
work (based on the write(2) man page and how it works on linux).  It's
more like asynchronous write than non-blocking write.  Using O_NONBLOCK
instead of O_NDELAY doesn't change the behavior.

Thanks,

Wayne


#include <stdio.h>
#include <ctype.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <assert.h>

main()
{
    int i, fd, fd2, len;
    struct hostent *hp;
    struct protoent *pp;
    char hostname[64];
    struct sockaddr_in lAddr, rAddr;
    char* data;
    int datalen, datapos;
    
    gethostname(hostname, 64);
    pp = getprotobyname("tcp");
    hp = gethostbyname(hostname);
    
    assert(pp && hp);
    
    fd = socket(AF_INET, SOCK_STREAM, pp->p_proto);
    assert(fd >= 0);
    
    lAddr.sin_family = hp->h_addrtype;
    memcpy((char *)&lAddr.sin_addr.s_addr, (char *)hp->h_addr,
	   sizeof(lAddr.sin_addr.s_addr));
    lAddr.sin_port = htons(12345);
    
    i = bind(fd, (struct sockaddr *)&lAddr, sizeof(lAddr));
    assert(i >= 0);
    
    printf("listening to port %d host %s (%s)\n", ntohs(lAddr.sin_port),
	   hostname, inet_ntoa(lAddr.sin_addr));
    i = listen(fd, 5);
    assert(i >= 0);
    
    len = sizeof(rAddr);
    memset(&rAddr, 0, sizeof(rAddr));
    fd2 = accept(fd, (struct sockaddr *)&rAddr, &len);
    assert(fd2 >= 0);
    
    printf("got connection from %s\n", inet_ntoa(rAddr.sin_addr));
    
    i = fcntl(fd2, F_SETFL, O_NDELAY);
    assert(i >= 0);
    
    datalen = (int) 1e8;
    data = (char *) malloc(datalen);
    datapos = 0;
    
    while (datapos < datalen) {
	fd_set wfds;
	FD_ZERO(&wfds);
	FD_SET(fd2, &wfds);
	
	i = select(fd2 + 1, NULL, &wfds, NULL, NULL);
	assert(i == 1);
	
	printf("trying to write %d bytes\n", datalen - datapos);
	i = write(fd2, data + datapos, datalen - datapos);
	printf("%d bytes written\n", i);
	assert(i > 0);
	
	datapos += i;
	assert(datapos <= datalen);
    }
    printf("hit return to exit ");
    getchar();
    exit(0);
}


--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]