From: y@drug.COM (Yoshi Mizuno)
Subject: Please help with TLI (Sun-OS) problem!
Organization: Mizuno Pharmacies
Date: Thu, 27 Aug 1992 08:00:29 GMT



Hi, we encountered a problem trying to impliment our clinent/server application
using TLI. I wonder if anyone can help.  

When a fast machine (SUN Sparc 630 MP) sends a bunch of TCP/IP packets to
a slow machine (Sparc IPC) a lot of packets get dropped.  For example, doing
spray from a fast one to the slow one, we get:


(630MP to IPC)

yt@hana$ spray meto
sending 1162 packets of lnth 86 to meto ...
        in 10.4 seconds elapsed time,
        658 packets (56.63%) dropped
Sent:   111 packets/sec, 9.4K bytes/sec
Rcvd:   48 packets/sec, 4.1K bytes/sec

With this condition, the following test program fails.  We thought that TCP/IP
makes an error free connection. . .  What are we doing wrong?  Or, is this
the way TCP/IP is?  


Yoshi Mizuno, Pharm.D.             [][][]       UUCP:      uunet!drug!y
Mizuno Pharmacies                  []  []       INTERNET:  y@drug.COM
4-1-24 Yushima, Bunkyo-ku        [][][][]       ISDN:      +81-3-5684-7722
Tokyo 113 JAPAN                    []           G3 FAX:    +81-3-5684-7723



------------------------CUT HERE--------------------------------
/* tst.c */

/*	This is test program using TLI to access TCP/IP.
	Server send data to client.
	If this program is used with no arguments, then it is the server.
	If this program gets the name of the machine where the server is
	running as an argument, then it is the client.
	When packets get lost in transmission, the client blocks on t_rcv forever.
	I assume that the lost packets never get sent again.
*/

#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <tiuser.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

extern int t_errno;

void ErrFn();
#define Error()		ErrFn(__FILE__,__LINE__)
#define Assert(b)	if(!(b)) Error()
#define TLI_ERR		{ t_error("t_error"); Error(); }


#define nTimes		500
#define bufsize		256
#define iPort		5

main(argc,argv)
int argc;
char *argv[];
{
	int i, c, iR, g, fd;
	unsigned char buf[bufsize];

	switch(argc) {
	case 1:					/* no arguments, make server and send */
		fd = OpenServer();
		for( c=0; c<bufsize; c++ )
			buf[c] = c;
		for( i=0; i<nTimes; i++ ) {
			printf("put %d\n",i);
			iR = t_snd(fd,buf,bufsize,0);
			if(iR!=bufsize)  TLI_ERR;
		}
		break;
	case 2:					/* 1 argument is name of server machine, make client and receive */
		fd = OpenClient(argv[1]);
		for( i=0; i<nTimes; i++ ) {
			printf("get %d\n",i);
			for( c=0; c<bufsize; c++ ) {
				iR = t_rcv(fd,buf,1,&g);
				if(iR!=1)  TLI_ERR;
				if( *buf != c ) {
					printf("%d %d\n",*buf,c);
					Error();
				}
			}
		}
		break;
	default:
		Error();
	}
	sleep(60);
	printf("done\n");
	/* the fancy functions to close TLI don't work on Sun, so forget them */
	if( t_close(fd) < 0 )  TLI_ERR;
}

int OpenServer() {
	int fd;
	struct t_bind *pBind;
	struct sockaddr_in oSock;
	struct t_call *pCall;

	fd = t_open("/dev/tcp",O_RDWR,NULL);
	if( fd < 0 )  TLI_ERR;
	pBind = (struct t_bind*)t_alloc(fd,T_BIND,T_ALL);
	if(!pBind)  TLI_ERR;
	pBind->qlen = 1;

	oSock.sin_family = AF_INET;
	oSock.sin_addr.s_addr = INADDR_ANY;
	oSock.sin_port = iPort;
	pBind->addr.len = sizeof(struct sockaddr_in);
	memcpy(pBind->addr.buf,&oSock,sizeof(struct sockaddr_in));

	if( t_bind(fd,pBind,pBind) < 0 )  TLI_ERR;
	if( t_free((char*)pBind,T_BIND) < 0 )  TLI_ERR;
	pCall = (struct t_call*)t_alloc(fd,T_CALL,T_ADDR);
	if(!pCall)  TLI_ERR;
	if( t_listen(fd,pCall) < 0 )  TLI_ERR;
	if( t_accept(fd,fd,pCall) < 0 )  TLI_ERR;
	if( t_free((char*)pCall,T_CALL) < 0 )  TLI_ERR;
	return fd;
}

int OpenClient(sHost)
char *sHost;
{
	int fd;
	struct t_call *pCall;
	struct sockaddr_in oSock;
	struct hostent *pHost;

	fd = t_open("/dev/tcp",O_RDWR,NULL);
	if( fd < 0 )  TLI_ERR;
	if( t_bind(fd,NULL,NULL) < 0 )  TLI_ERR;
	pCall = (struct t_call*)t_alloc(fd,T_CALL,T_ADDR);
	if(!pCall)  TLI_ERR;

	oSock.sin_family = AF_INET;
	pHost = gethostbyname(sHost);
	Assert(pHost);
	memcpy(&oSock.sin_addr,pHost->h_addr,pHost->h_length);
	oSock.sin_port = iPort;
	pCall->addr.len = sizeof(struct sockaddr_in);
	memcpy(pCall->addr.buf,&oSock,sizeof(struct sockaddr_in));

	if( t_connect(fd,pCall,NULL) < 0 ) {
		if(t_errno==TLOOK)  printf("t_look=%x\n",t_look(fd));
		TLI_ERR;
	}
	if( t_free((char*)pCall,T_CALL) < 0 )  TLI_ERR;
	return fd;
}

void ErrFn(s,i)
char *s;
int i;
{
	printf(" %s %d\n",s,i);
	exit(1);
}

-- 
Yoshi Mizuno, Pharm.D.             [][][]       UUCP:	   uunet!drug!y
Mizuno Pharmacies                  []  []       INTERNET:  y@drug.COM
4-1-24 Yushima, Bunkyo-ku        [][][][]       ISDN:      +81-3-5684-7722
Tokyo 113 JAPAN                    []           G3 FAX:    +81-3-5684-7723
Newsgroups: comp.sys.sun.misc