[comp.sys.mac.programmer] TCP with MPW 3.0 C

matt@zycor.UUCP (Matt Payne) (03/08/90)

I'm interesting in writing programs that communicate with a UNIX
(HP-UX) box via TCP/IP.   What tools do I need on the Mac?   Are 
there example programs available via ftp from somewhere? 
I'm using MPW 3.0 & C.   


Thank you very much for any pointers!

- matt 

uunet!ssbell!zycor!uumatt!matt

zben@umd5.umd.edu (Ben Cranston) (03/09/90)

In article <9@zycor.UUCP> matt@zycor.UUCP (Matt Payne) writes:

> I'm interesting in writing programs that communicate with a UNIX
> (HP-UX) box via TCP/IP.   What tools do I need on the Mac?   Are 
> there example programs available via ftp from somewhere? 
> I'm using MPW 3.0 & C.   

Here's a simple receiver for the following Mac program:

/* Internet connection test stub.
 * Wait for connection to TCP port, dump incoming data to standard output.
 * Ben Cranston 5/19/88
 * Mod 2/15/89 lose the newline
 */

#define PORTNUMM 1069
#define BUFFSIZE 132

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>

puntprog(s)
char *s;
{
    fprintf(stderr,"%s\n",s);
    exit(1);
}

main(argc,argv)
int argc;
char **argv;
{
    static struct sockaddr_in sockaddr = { AF_INET };
    static int sockalen = sizeof sockaddr;
    int sock;
    int stat;
    char netibuff[BUFFSIZE];

    sock = PORTNUMM;
    if (argc>1)
	sock = atoi( argv[1] );
    fprintf(stderr,"Listening on port %d\n",sock);
    sockaddr.sin_port = htons( sock );

    if ( 0 > (sock=socket(AF_INET,SOCK_STREAM,0)) )
	puntprog("listener: socket failed");

    if ( 0 > bind(sock,&sockaddr,sockalen) )
	puntprog("listener: bind failed");

    if ( 0 > listen(sock,1) )
	puntprog("listener: listen failed");

    if ( 0 > (sock = accept(sock,&sockaddr,&sockalen)) )
	puntprog("listener: accept failed");

    fprintf(stderr,"(open)\n");

    do {
	stat = read(sock,netibuff,BUFFSIZE);
	if (stat>0) {
	    write(1,netibuff,stat);
/*	    putchar('\n'); */
	}
    } while (stat>0);
}

Here's a simple C program that prints "Hello, World" on a remote Unix machine:
Please change the 128.8.10.5 to the machine you are running the above on...

/*
 * Test program to send hello world over the network.
 */

#define SRBUFLEN 8192

#include <Types.h>
#include <Devices.h>

#include "MacTCPCommonTypes.h"
#include "TCPPB.h"

pascal void ANRoutine(tcpStream,eventCode,userDataPtr,
	terminReason,icmpMsg)
StreamPtr tcpStream;
unsigned short eventCode;
Ptr userDataPtr;
unsigned short terminReason;
struct ICMPReport *icmpMsg;
{

}

OSErr OpenStream(DRefNum,BufPtr,TheStream)
short DRefNum;
char *BufPtr;
StreamPtr* TheStream;
{
	TCPiopb IOPB;
	OSErr Stat;

	IOPB.ioCRefNum = DRefNum;
	IOPB.csCode = TCPCreate;
	IOPB.csParam.create.rcvBuff = BufPtr;
	IOPB.csParam.create.rcvBuffLen = SRBUFLEN;
	IOPB.csParam.create.notifyProc = ANRoutine;

	if (0 != (Stat = PBControl( (ParmBlkPtr) &IOPB, false )) ) 
		return(Stat);

	(*TheStream) = IOPB.tcpStream;
	return(0);
}

OSErr CloseStream(DRefNum,TheStream)
short DRefNum;
StreamPtr TheStream;
{
	TCPiopb IOPB;

	IOPB.ioCRefNum = DRefNum;
	IOPB.csCode = TCPRelease;
	IOPB.tcpStream = TheStream;

	return( PBControl( (ParmBlkPtr) &IOPB, false ) );
}

OSErr OpenCircuit(DRefNum,TheStream,DestIP,DestPort)
short DRefNum;
StreamPtr TheStream;
int DestIP;
short DestPort;
{
	TCPiopb IOPB;

	IOPB.ioCRefNum = DRefNum;
	IOPB.csCode = TCPActiveOpen;
	IOPB.tcpStream = TheStream;
	IOPB.csParam.open.validityFlags = 0;
	IOPB.csParam.open.commandTimeoutValue = 20;
	IOPB.csParam.open.remoteHost = DestIP;
	IOPB.csParam.open.remotePort = DestPort;
	IOPB.csParam.open.localHost = 0; /* MacTCP fills in */
	IOPB.csParam.open.localPort = 1068;
	IOPB.csParam.open.dontFrag = false;
	IOPB.csParam.open.timeToLive = 20;
	IOPB.csParam.open.security = 0;
	IOPB.csParam.open.optionCnt = 0; /* no options */

	return( PBControl( (ParmBlkPtr) &IOPB, false ) );
}

OSErr WriteString(DRefNum,TheStream,TheString)
short DRefNum;
StreamPtr TheStream;
char* TheString;
{
	wdsEntry wds[2];
	TCPiopb IOPB;

	wds[0].length = strlen(TheString);
	wds[0].ptr = TheString;
	wds[1].length = 0;

	IOPB.ioCRefNum = DRefNum;
	IOPB.csCode = TCPSend;
	IOPB.tcpStream = TheStream;
	IOPB.csParam.send.validityFlags = 0;
	IOPB.csParam.send.urgentFlag = false;
	IOPB.csParam.send.pushFlag = true;
	IOPB.csParam.send.wdsPtr = (char *) wds;

	return( PBControl( (ParmBlkPtr) &IOPB, false ) );
}

main ()
{
	OSErr Stat;
	short DRefNum;
	int dest;
	ip_addrbytes buff;
	StreamPtr TheStream;
	char ReadBuff[SRBUFLEN];

	if (0 != (Stat=OpenDriver("\p.IPP",&DRefNum)) ) {
		printf("OpenDriver error, status %d\n",Stat);
		exit(-2);
	}

	if ( 0 != (Stat=OpenStream(DRefNum,&ReadBuff,&TheStream)) ) {
		printf("OpenStream error %d\n",Stat);
		exit(-2);
	}
	
	buff.a.byte[0] = 128;
	buff.a.byte[1] = 8;
	buff.a.byte[2] = 10;
	buff.a.byte[3] = 5;
	dest = buff.a.addr;

	if ( 0 != (Stat=OpenCircuit(DRefNum,TheStream,dest,1069)) ) {
		printf("OpenCircuit error %d\n",Stat);
		exit(-2);
	}
	
	if ( 0 != (Stat=WriteString(DRefNum,TheStream,"Hello, World!\n\r")) ) {
		printf("WriteString error %d\n",Stat);
		exit(-2);
	}

	if ( 0 != (Stat=CloseStream(DRefNum,TheStream)) ) {
		printf("CloseStream error %d\n",Stat);
		exit(-2);
	}
}

-- 

"It's all about Power, it's all about Control
 All the rest is lies for the credulous"
-- Man-in-the-street interview in Romania one week after Ceaucescu execution.