lkml.org 
[lkml]   [1999]   [Feb]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: PROBLEM: Sending mail-attachment > 45k with Netscape via sendmail hangs


> That stall is clean - the one end isnt reading data. That means either there
> is a problem where the kernel forgot to wake the other end (quite possible)
> or the user application is selecting on the wrong thing/busy/whatever

Well, strace says for the receiver:

select(4, [3], NULL, NULL, NULL) = 1 (in [3])
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 15) = 15
select(4, [3], NULL, NULL, NULL) = 1 (in [3])
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 15) = 15
select(4, [3], NULL, NULL, NULL) = 1 (in [3])
read(3, "\0\0\0\0\0\0\0\0\0\0", 15) = 10
select(4, [3], NULL, NULL, NULL <unfinished ...>

The blocking select() call is the same as the select()
calls before. And even if the receiver would be busy,
netstat should report data in the Recv-Q, right? It doesn't.
Instead it reports data in the Send-Q of the sender.

>
> You said you had a simple demo app, for this - can you let me have a look at
> it

I have attached client.c, serv.c and Makefile. Serv listens on port 3333
and forks on incoming connections. Then it sends about 5Mb of data.
Usually the client stalls after reading 30kb.
Note the #define READ_SIZE 15. When increasing READ_SIZE to >>100 bytes,
the connection does not stall.
Matthias
WARNS = -Wall -Wshadow
#CFLAGS = -c -O2 $(WARNS)
CFLAGS = -c -g $(WARNS)
#LDFLAGS = -s
MKDEP = gcc >.depend -MM $(CFLAGS)

OBJS = serv.o client.o

all: serv client

serv: serv.o
$(CC) $(LDFLAGS) serv.o -o $@

client: client.o
$(CC) $(LDFLAGS) client.o -o $@

$(OBJS): %.o: %.c
$(CC) $(CFLAGS) $< -o $@

clean::
rm -f *.o *~ serv client

depend::
$(MKDEP) *.c

ifeq (.depend,$(wildcard .depend))
include .depend
endif
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/time.h>
#include <sys/socket.h>
#define PORT 3333
#define READ_SIZE 15
static char buffer[READ_SIZE];
int main()
{
struct sockaddr_in addr;
struct hostent *hostent;
int sock, flgs, len, cnt, i;
fd_set rfds;
if(!(hostent = gethostbyname("localhost")))
{ printf("Could not resolve host!\n"); exit(1); }
addr.sin_port = htons(PORT);
addr.sin_family = hostent->h_addrtype;
memcpy(&addr.sin_addr, hostent->h_addr, hostent->h_length);
if((sock = socket(addr.sin_family, SOCK_STREAM, 0)) < 0)
{ perror("socket()"); exit(1); }
while( (i = connect(sock, (struct sockaddr*)&addr, sizeof(addr))) < 0
&& errno == EINTR )
;
if(i != 0)
{ perror("connect()"); exit(1); }
flgs = fcntl(sock, F_GETFL, 0);
fcntl(sock, F_SETFL, flgs|O_NONBLOCK);
cnt = 0;
do
{
FD_ZERO(&rfds);
FD_SET(sock, &rfds);
if(select(sock + 1, &rfds, NULL, NULL, NULL) <= 0)
{ perror("select()"); exit(1); }
len = read(sock, buffer, READ_SIZE);
if(len > 0)
cnt += len;
} while(len>0);
close(sock);
printf("Got %d bytes.\nConnection closed\n", cnt);

return 0;
}#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/un.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <signal.h>
#define PORT 3333
#define WRITE_SIZE 1585
static const char str[WRITE_SIZE];
static int mainSock;
static void sigint(int s)
{
printf("***SIGINT\n");
fflush(stdout);
close(mainSock);
exit(0);
}
int main()
{
int pid, sock;
struct sockaddr_in addr, accept_addr;
int addrlen = 0;
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = INADDR_ANY;
if((mainSock = socket(addr.sin_family, SOCK_STREAM, 0)) < 0)
{ perror("socket()"); exit(1); }
signal(SIGINT, sigint);
if( bind(mainSock, &addr, sizeof(addr)) < 0)
{ perror("bind()"); exit(1); }
if( listen(mainSock, 1) < 0)
{ perror("listen()"); exit(1); }
while(1)
{
sock = accept(mainSock, (struct sockaddr *)&accept_addr, &addrlen);
if(sock < 0) { perror("accept()"); exit(1); }
if((pid = fork()) > 0)
{
int status;
close(sock);
wait(&status); /* Wait for child */
printf("child gone\n");
continue;
}
if(!pid) /* Child proc */
{
int i, size, written, flgs;
const char *ptr;
fd_set wfds;
flgs = fcntl(sock, F_GETFL, 0);
fcntl(sock, F_SETFL, flgs|O_NONBLOCK);
printf("sending data...\n");
for(i = 0; i < 3200; i++)
{
size = sizeof(str);
ptr = str;
while(size)
{
FD_ZERO(&wfds);
FD_SET(sock, &wfds);
if(select(sock+1, NULL, &wfds, NULL, NULL) < 0)
{ perror("select()"); abort(); }
if((written = write(sock, ptr, size)) < 0)
{ perror("write()"); abort(); }
size -= written;
ptr += written;
}
}
printf("ready\n");fflush(stdout);
close(sock);
abort();
}
}
return 0;
}
\
 
 \ /
  Last update: 2005-03-22 13:50    [from the cache]
©2003-2014 Jasper Spaans. Advertise on this site