Listing 1: TEST.FOR
===================
Program Test
C
character*15 SERVER
character*100 COMMAND
character*1000 BUFFER
c
integer PORT
integer SOCKET
integer TCPOpen
integer TCPClose
integer TCPTransfer
c
SERVER = 'MyPC' ! use the area's server name
PORT = 12345 ! use the area's port number
c
SOCKET = TCPOpen(SERVER,PORT)
if (SOCKET .NE. -1) THEN
COMMAND = 'RALL'
icount = TCPTransfer(SOCKET,COMMAND,BUFFER)
if (icount .NE. -1) call Print(BUFFER)
iret = TCPClose(SOCKET)
else
call exit
endif
c
end
subroutine Print(buffer)
c
character*(*) buffer
c
jpos = 1
jbeg = 1
50 continue
if (buffer(jpos:jpos) .eq. char(10)) then ! search for \n
write(6,*) buffer(jbeg:jpos-1)
jbeg = jpos + 1
endif
jpos = jpos + 1
if (jpos .ge. 1000) go to 100
go to 50
c
100 return
end
Listing 2: fsubs.c
==================
/*
TCP/IP subroutine package for VAX Fotran
*/
#include <types.h>
#include <socket.h>
#include <in.h>
#include <netdb.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#define MAXLEN 2048 /* max command buffer length */
#define BACKLOG 5 /* max outstanding connections */
#define FLAGS 0 /* flags argument, must be zero */
#define closesocket close
#define SOCKET int
typedef struct
{
unsigned short length;
unsigned char type;
unsigned char code;
char *pointer;
} DESC;
typedef struct sockaddr *LPSOCKADDR;
int TCPOpen(DESC *pserver, int *pport)
{
int status;
int namelength;
int shutdown_required = 0;
char localhost_s[MAXLEN];
char remothost_s[MAXLEN];
struct sockaddr_in l_socket_s;
struct sockaddr_in r_socket_s;
struct hostent *localhost_p;
struct hostent *remothost_p;
SOCKET l_socket;
char server[MAXLEN];
short int port;
int i;
/* Interface Fortran -> C */
strncpy(server,pserver->pointer,pserver->length);
for (i=0; i<pserver->length; i++)
if (server[pserver->length-i-1] != ' ')
break;
server[pserver->length-i] = '\0';
port = *pport;
/* Create a socket */
l_socket = socket ( AF_INET, SOCK_STREAM, 0 );
if ( l_socket == -1 )
{
printf ("** Error Creating Socket **\n");
return -1;
}
/* Get hostname */
gethostname(localhost_s,sizeof(localhost_s));
localhost_p = gethostbyname ( localhost_s );
if ( localhost_p == NULL )
{
printf ("** Cannot get hostaddress of %s **\n",localhost_s);
return -1;
}
/* bind socket to port */
l_socket_s.sin_family = AF_INET;
l_socket_s.sin_port = htons ( 0 );
l_socket_s.sin_addr.s_addr = 0;
memcpy((char*)&(l_socket_s.sin_addr), localhost_p->h_addr, localhost_p->h_length);
status = bind ( l_socket, (LPSOCKADDR)&l_socket_s, sizeof(l_socket_s));
if ( status == -1 )
{
printf ("** Error Binding Socket, errno = %d **\n",errno);
shutdown ( l_socket , 2 );
return -1;
}
/* Get Server name */
strcpy(remothost_s,server);
remothost_p = gethostbyname ( remothost_s );
if ( remothost_p == NULL )
{
printf ("** Cannot get server address %s **\n",remothost_s);
return -1;
}
/* Connect to Server socket */
r_socket_s.sin_family = AF_INET;
r_socket_s.sin_port = htons ( (unsigned short)port );
r_socket_s.sin_addr.s_addr = *(unsigned long *) *(remothost_p->h_addr_list);
namelength = sizeof ( r_socket_s );
status = connect ( l_socket, (LPSOCKADDR)&r_socket_s, namelength );
if ( status == -1)
{
printf ("** Error connecting to Server **\n");
shutdown ( l_socket , 2 );
return -1;
}
return (l_socket);
}
int TCPClose(SOCKET *socket)
{
int retval;
SOCKET l_socket = *socket;
retval = closesocket( l_socket );
return retval;
}
int TCPTransfer(SOCKET *socket, DESC *command, DESC *buffer)
{
int i, z, status;
int count;
struct timeval timeout;
fd_set readfds;
int msecs = 4000;
SOCKET l_socket;
char command_s[MAXLEN];
char r_buffer[MAXLEN];
char *ptr;
/* Interface Fortran -> C */
l_socket = *socket;
strncpy(command_s,command->pointer,command->length);
for (i=0; i<command->length; i++)
if (command_s[command->length-i-1] != ' ')
break;
command_s[command->length-i] = '\0';
count = send ( l_socket, command_s, strlen(command_s) + 1, FLAGS );
if ( count == -1)
{
printf ("** Error sending data **\n");
return -1;
}
z = 0;
while(1)
{
if (msecs > 0)
{
FD_ZERO(&readfds);
FD_SET(l_socket,&readfds);
timeout.tv_sec = msecs / 1000;
timeout.tv_usec = (msecs % 1000) * 1000;
status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
if (status == -1)
{
printf ("** Error while selecting **\n");
return 0;
}
if (!FD_ISSET(l_socket,&readfds))
{
printf ("** Timeout while selecting **\n");
r_buffer[z] = '\0'; // terminate it by adding a '\0'
z++;
break;
}
}
count = recv ( l_socket, &r_buffer[z], MAXLEN, FLAGS );
if ( count == -1 )
{
printf ("** Error receiving answer **\n");
return -1;
}
else
z += count;
if (r_buffer[z-1] == '\0') // termination has arrived
break;
}
/* Interface C -> Fortran */
strncpy(buffer->pointer,r_buffer,z-1);
ptr = (char *)(buffer->pointer + z-1);
*ptr++ = '\n'; /* terminate with LF */
memset(ptr,' ',buffer->length-z); /* fill rest with blanks */
return z;
}
Listing 3: Compilation and Linking
==================================
$cc/vaxc fsubs.c
$fortran test.for
$link test + fsubs + sys$library:ucx$ipc/lib + sys$library:vaxcrtl/lib
|