The Internet and JAVA


If you're an ardent supporter of JAVA & believe in it utterly, then we recommend that you don't read this tutorial. This is our effort to show you that Java, like Netscape, is dependent on the WinSock API for all its Internet needs. It'll be best if you go through our tutorial on Netscape first as this topic is discussed in greater detail there. We'll be employing similar methods here.

Sun would have us believe that Java is the next best thing to sliced bread and nearly half the world does ! What we want to show you here is that the much wanted Java calls WinSock code when it wants to do anything with the Internet, just like everybody else.

We've used Windows 95 as our Operating System throughout as Java requires a 32-bit OS. Our test program is a small applet that goes to the specified site and downloads a page from there. It then displays the page in a list box. You don't need extensive work experience with Java to try these examples out, all you need is JDK 1.0. (These programs have been tried out with JDK 1.0)

Compile the program given below (zzz.java) and then run it through appletviewer or view it through a Java enabled browser like Netscape.

zzz.java

import java.awt.*;
import java.applet.*;
import java.net.*;
import java.io.*;
public class zzz extends Applet
{
       URL u;
       URLConnection c;
       InputStream n;
       DataInputStream d;
       String s;
       List l;
       public void init()
       {
               setLayout(new BorderLayout());
               l = new List(3000,false);
               add("Center",l);
               add("North",new Button("Start"));
       }
       public boolean action ( Event e, Object o)
       {
       if ( "Start".equals(o) )
       {       try
               {       u=new URL("http://70.0.0.10/");
                       showStatus(" URL is initialised ");
                       c = u.openConnection();
                       showStatus("Open Connection successful");
               }
               catch(Exception x)
               {       showStatus("error in URL/Connection");
               }
               try
               {       n = c.getInputStream();
                       showStatus("Input Stream Open successful");
               }
               catch(Exception x)
               {       showStatus("error in get Input Stream");
                       return true;
               }
               try
               {       d=new DataInputStream(n);
                       showStatus(" Data Input Stream Open successful");
               }
               catch(Exception x)
               {       showStatus ("error in Data Input Stream");
                       return true;
               }
               try
               {       while ((s=d.readLine()) != null )
                               l.addItem(s);
                       n.close();
               }
               catch(Exception x)
               {       showStatus("Add Item not successful");
                       return true;
               }
       }
       return false;
   }
}

To compile a .java file use the command

javac zzz.java

a.html

<applet code=zzz width=200 height=200></applet>

Compilation Tip:

You need an HTML crash course ( you don't compile a HTML file )

Tip (provided you are new to the world of JAVA):-

To run this applet use command

appletviewer a.html

Important

You must set the CLASSPATH variable to the directory of zzz.class

c:\yyz>set CLASSPATH=.;%CLASSPATH%

Now that our applet's ready, let's create a fresh Wsock32.dll and replace the original with it. Every time we run our applet, a file z.txt is created which holds the name of every function called by Java. Examining this file will give us a lot of information about what's happening under Java's fancy hood.

We've used Visual C++ 4.0 for all these programs. Create a project to make a .dll. Name the project yyz and then add the code given below to a file yyz.def. It's in the .def file that you "export" your functions so that they can be called by other programs.

Before you do this be sure to copy the original wsock32.dll somewhere else !

Tip: When the project is built we get the file yyz.dll in the debug directory. Instead of copying the .dll into C:\Windows\System by hand each time, simply create a batch file copydll.bat with the following commands

	Copy  c:\yyz\debug\yyz.dll c:\windows\system\wsock32.dll
	del c:\z.txt 

yyz.def

LIBRARY yyz
DESCRIPTION "wsock function"
EXPORTS
	WSAAsyncGetHostByAddr @102
	WSAAsyncGetHostByName @103
	WSAAsyncGetProtoByName @105
	WSAAsyncGetProtoByNumber @104
	WSAAsyncGetServByName @107
	WSAAsyncGetServByPort @106
	WSAAsyncSelect @101
	WSACancelAsyncRequest @108
	WSACancelBlockingCall @113
	WSAGetLastError @111
	WSAIsBlocking @114
	WSARecvEx @1107
	WSASetBlockingHook @109
	WSASetLastError @112
	WSAStartup @115
	WSAUnhookBlockingHook @110
	accept @1
	bind @2
	closesocket @3
	connect @4
	gethostbyaddr @51
	gethostbyname @52
	gethostname @57
	getpeername @5
	getprotobyname @53
	getprotobynumber @54
	getservbyname @55
	getservbyport @56
	getsockname @6
	getsockopt @7
	htonl @8
	htons @9
	inet_addr @10
	inet_ntoa @11
	ioctlsocket @12
	listen @13
	ntohl @14
	ntohs @15
	recv @16
	recvfrom @17
	select @18
	send @19
	sendto @20
	setsockopt @21
	shutdown @22
	socket @23
	WSACleanup @116
	__WSAFDIsSet @151
	s_perror @1108
	TransmitFile @1140
	EnumProtocolsA @1111
	EnumProtocolsW @1112
	GetAddressByNameA @1109
	GetAddressByNameW @1110
	GetNameByTypeA  @1115
	GetNameByTypeW  @1116
	GetServiceA  @1119
	GetServiceW  @1120
	GetTypeByNameA  @1113
	GetTypeByNameW  @1114
	SetServiceA  @1117
	SetServiceW  @1118
	NPLoadNameSpaces @1130
	dn_expand @1106
	inet_network @1100
	rexec @1103
	rresvport @1104
	WsControl
	DllMain	

yyz.c

#include <windows.h>
#include <stdio.h>

void abc(char * p)
{
FILE *fp=fopen("c:\\z.txt","a+");
fprintf(fp,"%s\n",p);
fclose(fp);
}

char aa[1000];
BOOL WINAPI DllMain( HINSTANCE  hinstDLL,DWORD  fdwReason,LPVOID  lpvReserved)
{
	abc("DllMain");
        return 1;
}
SOCKET PASCAL FAR accept (SOCKET s, struct sockaddr FAR *addr,int FAR *addrlen)
{
abc("accept ");
return 0;
}
int PASCAL FAR closesocket (SOCKET s)
{
abc("closesocket ");
return 0;
}
int PASCAL FAR connect (SOCKET s, const struct sockaddr FAR *name, int namelen)
{
abc("connect ");
return 0;
}
int PASCAL FAR ioctlsocket (SOCKET s, long cmd, u_long FAR *argp)
{
abc("ioctlsocket ");
return 0;
}
int PASCAL FAR getpeername (SOCKET s, struct sockaddr FAR *name,
                            int FAR * namelen)
{
abc("getpeername ");
return 0;
}
int PASCAL FAR getsockname (SOCKET s, struct sockaddr FAR *name,
                            int FAR * namelen)
{
abc("getsockname ");
return 0;
}
int PASCAL FAR getsockopt (SOCKET s, int level, int optname,
                           char FAR * optval, int FAR *optlen)
{
abc("getsockopt ");
return 0;
}
u_long PASCAL FAR htonl (u_long hostlong)
{
abc("htonl ");
return 0;
}
char FAR * PASCAL FAR inet_ntoa (struct in_addr in)
{
abc("inet_ntoa ");
return 0;
}
int PASCAL FAR listen (SOCKET s, int backlog)
{
abc("listen ");
return 0;
}
u_long PASCAL FAR ntohl (u_long netlong)
{
abc("ntohl ");
return 0;
}
u_short PASCAL FAR ntohs (u_short netshort)
{
abc("ntohs ");
return 0;
}
int PASCAL FAR recvfrom (SOCKET s, char FAR * buf, int len, int flags,
                         struct sockaddr FAR *from, int FAR * fromlen)
{
abc("recvfrom ");
return 0;
}
int PASCAL FAR select (int nfds, fd_set FAR *readfds, fd_set FAR *writefds,
                       fd_set FAR *exceptfds, const struct timeval FAR *timeout)
{
abc("select ");
return 0;
}
int PASCAL FAR sendto (SOCKET s, const char FAR * buf, int len, int flags,
                       const struct sockaddr FAR *to, int tolen)
{
abc("sendto ");
return 0;
}
int PASCAL FAR shutdown (SOCKET s, int how)
{
abc("shutdown ");
return 0;
}
struct hostent FAR * PASCAL FAR gethostbyaddr(const char FAR * addr,
                               int len, int type)
{
abc("gethostbyaddr");
return 0;
}
struct hostent FAR * PASCAL FAR gethostbyname(const char FAR * name)
{
abc("gethostbyname");
return 0;
}
int PASCAL FAR gethostname (char FAR * name, int namelen)
{
abc("gethostname ");
return 0;
}
struct servent FAR * PASCAL FAR getservbyport(int port, const char FAR * proto)
{
abc("getservbyport");
return 0;
}
struct servent FAR * PASCAL FAR getservbyname(const char FAR * name,
                                              const char FAR * proto)
{
abc("getservbyname");
return 0;
}
struct protoent FAR * PASCAL FAR getprotobynumber(int proto)
{
abc("getprotobynumber");
return 0;
}
struct protoent FAR * PASCAL FAR getprotobyname(const char FAR * name)
{
abc("getprotobyname");
return 0;
}
int PASCAL FAR WSAStartup(WORD wVersionRequired, LPWSADATA lpWSAData)
{
abc("WSAStartup");
return 0;
}
int PASCAL FAR WSACleanup(void)
{
abc("WSACleanup");
return 0;
}
void PASCAL FAR WSASetLastError(int iError)
{
abc("WSASetLastError");
return 0;
}
int PASCAL FAR WSAGetLastError(void)
{
abc("WSAGetLastError");
return 0;
}
BOOL PASCAL FAR WSAIsBlocking(void)
{
abc("WSAIsBlocking");
return 0;
}
int PASCAL FAR WSAUnhookBlockingHook(void)
{
abc("WSAUnhookBlockingHook");
return 0;
}
FARPROC PASCAL FAR WSASetBlockingHook(FARPROC lpBlockFunc)
{
abc("WSASetBlockingHook");
return 0;
}
int PASCAL FAR WSACancelBlockingCall(void)
{
abc("WSACancelBlockingCall");
return 0;
}
HANDLE PASCAL FAR WSAAsyncGetServByName(HWND hWnd, u_int wMsg,
   const char FAR * name,const char FAR * proto,
                                        char FAR * buf, int buflen)
{
abc("WSAAsyncGetServByName");
return 0;
}
HANDLE PASCAL FAR WSAAsyncGetServByPort(HWND hWnd, u_int wMsg, int port,
   const char FAR * proto, char FAR * buf,int buflen)
{
abc("WSAAsyncGetServByPort");
return 0;
}
HANDLE PASCAL FAR WSAAsyncGetProtoByName(HWND hWnd, u_int wMsg,
   const char FAR * name, char FAR * buf,int buflen)
{
abc("WSAAsyncGetProtoByName");
return 0;
}
HANDLE PASCAL FAR WSAAsyncGetProtoByNumber(HWND hWnd, u_int wMsg,
    int number, char FAR * buf,int buflen)
{
abc("WSAAsyncGetProtoByNumber");
return 0;
}
HANDLE PASCAL FAR WSAAsyncGetHostByName(HWND hWnd, u_int wMsg,
  const char FAR * name, char FAR * buf,int buflen)
{
abc("WSAAsyncGetHostByName");
return 0;
}
HANDLE PASCAL FAR WSAAsyncGetHostByAddr(HWND hWnd, u_int wMsg,
  const char FAR * addr, int len, int type,char FAR * buf, int buflen)
{
abc("WSAAsyncGetHostByAddr");
return 0;
}
int PASCAL FAR WSACancelAsyncRequest(HANDLE hAsyncTaskHandle)
{
abc("WSACancelAsyncRequest");
return 0;
}
int PASCAL FAR WSAAsyncSelect(SOCKET s, HWND hWnd, u_int wMsg,
                               long lEvent)
{
abc("WSAAsyncSelect");
return 0;
}
int PASCAL 	__WSAFDIsSet ()
{
abc("__WSAFDIsSet ");
return 0;
}
int PASCAL 	s_perror ()
{
abc("s_perror ");
return 0;
}
int PASCAL 	TransmitFile ()
{
abc("TransmitFile ");
return 0;
}
int PASCAL 	EnumProtocolsA ()
{
abc("EnumProtocolsA ");
return 0;
}
int PASCAL 	EnumProtocolsW ()
{
abc("EnumProtocolsW ");
return 0;
}
int PASCAL 	GetAddressByNameA ()
{
abc("GetAddressByNameA ");
return 0;
}
int PASCAL 	GetAddressByNameW ()
{
abc("GetAddressByNameW ");
return 0;
}
int PASCAL 	GetNameByTypeA  ()
{
abc("GetNameByTypeA  ");
return 0;
}
int PASCAL 	GetNameByTypeW  ()
{
abc("GetNameByTypeW  ");
return 0;
}
int PASCAL 	GetServiceA ()
{
abc("GetServiceA ");
return 0;
}
int PASCAL 	GetServiceW ()
{
abc("GetServiceW ");
return 0;
}
int PASCAL 	GetTypeByNameA ()
{
abc("GetTypeByNameA ");
return 0;
}
int PASCAL 	GetTypeByNameW ()
{
abc("GetTypeByNameW ");
return 0;
}
int PASCAL 	SetServiceA ()
{
abc("SetServiceA ");
return 0;
}
int PASCAL 	SetServiceW  ()
{
abc("SetServiceW  ");
return 0;
}
int PASCAL 	dn_expand ()
{
abc("dn_expand ");
return 0;
}
int PASCAL 	inet_network ()
{
abc("inet_network ");
return 0;
}
int PASCAL 	rexec ()
{
abc("rexec ");
return 0;
}
int PASCAL 	rresvport ()
{
abc("rresvport ");
return 0;
}
int PASCAL WSARecvEx ()
{
abc("WSARecvEx ");
return 0;
}
unsigned long PASCAL FAR inet_addr (const char FAR * cp)
{
abc("inet_addr ");
return 0;
}
u_short PASCAL FAR htons (u_short hostshort)
{
abc("htons ");
return 0;
}
SOCKET PASCAL FAR socket (int af, int type, int protocol)
{
abc("socket ");
return 0;
}
int PASCAL FAR bind (SOCKET s, const struct sockaddr FAR *addr, int namelen)
{
abc("bind ");
return 0;
}
int PASCAL FAR setsockopt (SOCKET s, int level, int optname,
                           const char FAR * optval, int optlen)
{
abc("setsockopt ");
return 0;
}
int PASCAL FAR recv (SOCKET s, char FAR * buf, int len, int flags)
{
abc("recv ");
return 0;
}
int PASCAL FAR send (SOCKET s, const char FAR * buf, int len, int flags)
{
abc("send ");
return 0;
}
int PASCAL WsControl(void *i1,void *i2,void *i3,void *i4,void *i5,void *i6)
{
abc("WsControl");
return 0;
}
int PASCAL 	NPLoadNameSpaces (void *i1,void *i2,void *i3)
{
abc("NPLoadNameSpaces ");
return 0;
}

Once everything's in place (yyz.dll copied to windows\system ) we run the applet. Examing the file z.txt shows us that Java calls our dll function just as if it would the real ones. Since every function but DllMain returns a zero , Java assumes that the function call was succesful and moves ahead.

z.txt

DllMain
WSAStartup
socket 
setsockopt 
gethostname 
gethostbyname
inet_addr 
htons 
htonl 
connect 
getsockname 
ntohs 
send 
send 

As we can see in the file, the function connect() was called by Java and it was fooled into believing that the call was successful. Java can't double check on the WinSock so it blunders on, trusting us completely.

After getsockname there starts an endless array of function calls to send(). Since we're returning a 0 in this function, Java assumes that the function failed and it calls it repeatedly.

Now that we know the names of the WinSock functions called by Java, lets check the parameters it passes to the procedures. Make the changes given below to the .c file and copy the dll to windows\system after compilation.


int PASCAL FAR WSAStartup(WORD wVersionRequired, LPWSADATA lpWSAData)
{
	sprintf(aa,"wVersionRequired ...%u",wVersionRequired);
	abc(aa);
	abc("WSAStartup");
	return 0;
}

Just like Netscape, Java too requires the same version of WinSock i.e 1.01.

z.txt

DllMain
WSAStartup
wVersionRequired...257
socket 
setsockopt 
gethostname 
gethostbyname
inet_addr 
htons 
htonl 
connect 
getsockname 
ntohs 
send 

Add this code to WSAStartup() to correctly initialize the structure WSADATA. This is crucial if you want Java to work properly.

int PASCAL FAR WSAStartup(WORD wVersionRequired, LPWSADATA lpWSAData)
{
	sprintf(aa,"wVersionRequired ...%u",wVersionRequired);
	abc(aa);
	lpWSAData->wVersion=257;
	lpWSAData->wHighVersion=257;
	strcpy(lpWSAData->szDescription,"Microsoft Windows Sockets Version 	1.1.");
	strcpy(lpWSAData->szSystemStatus,"Running on Windows 95.");
	lpWSAData->iMaxSockets=256;
	lpWSAData->iMaxUdpDg=65467;
	lpWSAData->lpVendorInfo=0;
	abc("WSAStartup");
	return 0;
}

z.txt

DllMain
WSAStartup
wVersionRequired...257
socket 
setsockopt 
gethostname 
gethostbyname
inet_addr 
htons 
htonl 
connect 
getsockname 
ntohs 
send 

To convert the port number 80 into a Big Endian Number, Java calls htons(). Add this code to sniff out the parameters passed to this function.

u_short PASCAL FAR htons (u_short hostshort)
{
	abc("htons ");
	sprintf(aa,"htons....%u",hostshort);
	abc(aa);
	return 0;
}

z.txt

DllMain
WSAStartup
wVersionRequired...257
socket 
setsockopt 
gethostname 
gethostbyname
inet_addr 
htons 
htons....80
htonl 
connect 
getsockname 
ntohs 
send 
send 

Our next step is discovering the parameters that Java sends to the socket() function.

SOCKET PASCAL FAR socket (int af, int type, int protocol)
{
	abc("socket ");
	sprintf(aa,"af=%d..type=%d..protocol=%d",af,type,protocol);
	abc(aa);
	return 0;
}

z.txt

DllMain
WSAStartup
wVersionRequired...257
socket 
af=2..type=1..protocol=0
setsockopt 
gethostname 
gethostbyname
inet_addr 
htons 
htons....80
htonl 
connect 
getsockname 
ntohs 
send 

2 is the actual value of AF_INET, 1 is the value of SOCK_STREAM and the last value is for TCP/IP. Java unlike Netscape doesn't call WSAAsyncSelect, so all it's functions are blocking. That's rather shoddy programming but I guess there's nothing we can do about that.

int PASCAL FAR WSAAsyncSelect(SOCKET s, HWND hWnd, u_int wMsg,long lEvent)
{
	abc("WSAAsyncSelect");
	sprintf(aa,"WSAAsyncSelect - wMsg = %u...lEvent=%ld",wMsg,lEvent);
	abc(aa);
	return 0;
}

As you can see, including the function has no effect and we've got the output file to prove it.

z.txt

DllMain
WSAStartup
wVersionRequired...257
socket 
af=2..type=1..protocol=0
setsockopt 
gethostname 
gethostbyname
inet_addr 
htons 
htons....80
htonl 
connect 
getsockname 
ntohs 
send 
send 

Setsockopt() is used to fine tune the socket() by sending it extra parameters. Place this code in the .dll too.

int PASCAL FAR setsockopt (SOCKET s, int level, int optname,const char FAR * optval, int optlen)
{
	abc("setsockopt ");
	sprintf(aa,"level=%d..optname=%d..optval=%s.....optlen=%d",level,optname,optval,optlen);
	abc(aa);
	return 0;
}

z.txt

DllMain
WSAStartup
wVersionRequired...257
socket 
af=2..type=1..protocol=0
setsockopt 
level=65535..optname=4..optval=yes.....optlen=4
gethostname 
gethostbyname
inet_addr 
htons 
htons....80
htonl 
connect 
getsockname 
ntohs 
send 
send 

The next function we're going to maul is inet_addr(), a procedure that converts an IP address fron it's Dotted Decimal Notation to an actual long number.

unsigned long PASCAL FAR inet_addr (const char FAR * cp)
{
	abc("inet_addr ");
	sprintf(aa,"cp..%s",cp);
	abc(aa);
	return 0;
}

z.txt

DllMain
WSAStartup
wVersionRequired...257
socket 
af=2..type=1..protocol=0
setsockopt 
level=65535..optname=4..optval=yes.....optlen=4
gethostname 
gethostbyname
inet_addr 
cp..70.0.0.10
htons 
htons....80
htonl 
connect 
getsockname 
ntohs 
send 

Add this code to connect() to view the parameters passed to it.

int PASCAL FAR connect (SOCKET s, const struct sockaddr FAR *name, int namelen)
{
sprintf(aa,"socket..%ld..namelen...%d",s,namelen);
abc(aa);
sprintf(aa, "sa_family = %d.. sa_data = %s..%d. .namelen=%d..", name->sa_family, name->sa_data , 
name->sa_data[0], namelen );
abc(aa);
abc("connect ");
return 0;
}

z.txt

DllMain
WSAStartup
wVersionRequired...257
socket 
af=2..type=1..protocol=0
setsockopt 
level=65535..optname=4..optval=yes.....optlen=4
gethostname 
gethostbyname
inet_addr 
cp..70.0.0.10
htons 
htons....80
htonl 
connect 
socket..0..namelen...16
sa_family=2..sa_data = ..0..namelen=16..
getsockname 
ntohs 
send 
send 

In the earlier programs, send function returned a 0, which meant a failure, so Java continuously called the send function. Send has to return the number of bytes sent. The first three parameters to the send function are the socket number , an address location and the no. of bytes at the address location to be sent. So, we cleverly return the no. of bytes Java wants us to send i.e the third parameter thus fooling Java in believing that the data has been sent.

Even though we haven't specified the file we want from the web site, Java retrieves the default html/htm file . This is because internally Java sends a "GET /" to the server. This means send me your default HTML file.

Send() is called more than once. The first time, send() is called to send the HTTP command and the required headers i.e 'GET / HTTP/1.0' to the server. Additional headers may,maynot be sent to the server but Java chooses to send it so we have the second and the third send for the additional headers. And finally, a blank string(\r\n), indicating the end of data.

int PASCAL FAR send (SOCKET s, const char FAR * buf, int len, int flags)
{
	abc("send ");
	sprintf(aa,"buf=%s..len=%d..flags=%d",buf,len,flags);
	abc(aa);
	return len;
}

z.txt

DllMain
WSAStartup
wVersionRequired...257
socket 
af=2..type=1..protocol=0
setsockopt 
level=65535..optname=4..optval=yes.....optlen=4
gethostname 
gethostbyname
inet_addr 
cp..70.0.0.10
htons 
htons....80
htonl 
connect 
socket..0..namelen...16
sa_family=2..sa_data = ..0..namelen=16..
getsockname 
ntohs 
send 
buf=GET / HTTP/1.0
..len=16..flags=0
send 
buf=User-Agent: JDK/1.0
..len=21..flags=0
send 
buf=Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
..len=62..flags=0
send 
buf=
cept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
..len=2..flags=0
recv 
DllMain
WSACleanup
DllMain

The next function Java calls after the send() is recv() so, we've got to change recv() too. What we'll do is modify recv() to fool Java into believing that it's actually got stuff off the Internet. What we do is place some text in a buffer that Java'll notice and return the length of the data. You'll notice that we have made a small change to the dll as compared to Netscape. We have put some addtional data i.e. HTTP/1.0\r\n\r\n , as Java does not readily read simple text. The HTTP header has to be given first and then the text.

int PASCAL FAR recv (SOCKET s, char FAR * buf, int len, int flags)
{
	cnt++;
	abc("recv ");
	sprintf(aa,"buf=%s..len=%d..flags=%d..cnt=%d",buf,len,flags,cnt);
	abc(aa);
	if (cnt == 1)
	{
		memcpy(buf,"HTTP/1.0\r\n\r\n",12);
		return 12;
	}
	else 
	if (cnt == 2)
	{
		memcpy(buf,"Hello\r\n",7);
		return 7;
	}
	else
		return 0;
}

Miracles of miracles!! A Hello displayed on the screen. It works!!

When recv() is called for the first time, we simply give it the HTTP header, when called again, we give it the text and finally, since there is no more data to be sent, we give it a 0 to indicate the end.

z.txt

DllMain
WSAStartup
wVersionRequired...257
socket 
af=2..type=1..protocol=0
setsockopt 
level=65535..optname=4..optval=yes.....optlen=4
gethostname 
gethostbyname
inet_addr 
cp..70.0.0.10
htons 
htons....80
htonl 
connect 
socket..0..namelen...16
sa_family=2..sa_data = ..0..namelen=16..
getsockname 
ntohs 
send 
buf=GET / HTTP/1.0
..len=16..flags=0
send 
buf=User-Agent: JDK/1.0
..len=21..flags=0
send 
buf=Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
..len=62..flags=0
send 
buf=
cept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
..len=2..flags=0
recv 
buf=..len=2048..flags=0..cnt=1
recv 
buf=/Object;)Ljava/lang/StringBuffer;..len=2036..flags=0..cnt=2
recv 
buf=..len=2029..flags=0..cnt=3
DllMain
WSACleanup
DllMain

The final program and the output have been given below.

yyz.c

#include <windows.h>
#include <stdio.h>

void abc(unsigned char * p)
{
FILE *fp=fopen("c:\\z.txt","a+");
fprintf(fp,"%s\n",p);
fclose(fp);
}
int cnt;
char aa[1000];
BOOL WINAPI DllMain( HINSTANCE  hinstDLL,DWORD  fdwReason,LPVOID  lpvReserved)
{
	abc("DllMain");
        return 1;
}
SOCKET PASCAL FAR accept (SOCKET s, struct sockaddr FAR *addr,int FAR *addrlen)
{
abc("accept ");
return 0;
}
int PASCAL FAR closesocket (SOCKET s)
{
abc("closesocket ");
return 0;
}
int PASCAL FAR connect (SOCKET s, const struct sockaddr FAR *name, int namelen)
{
sprintf(aa,"socket..%ld..namelen...%d",s,namelen);
abc(aa);
sprintf(aa, "sa_family = %d.. sa_data = %s..%d. .namelen=%d..", name->sa_family, name->sa_data ,
name->sa_data[0], namelen );
abc(aa);
abc("connect ");
return 0;
}

int PASCAL FAR ioctlsocket (SOCKET s, long cmd, u_long FAR *argp)
{
abc("ioctlsocket ");
return 0;
}
int PASCAL FAR getpeername (SOCKET s, struct sockaddr FAR *name,
                            int FAR * namelen)
{
abc("getpeername ");
return 0;
}
int PASCAL FAR getsockname (SOCKET s, struct sockaddr FAR *name,
                            int FAR * namelen)
{
abc("getsockname ");
return 0;
}
int PASCAL FAR getsockopt (SOCKET s, int level, int optname,
                           char FAR * optval, int FAR *optlen)
{
abc("getsockopt ");
return 0;
}
u_long PASCAL FAR htonl (u_long hostlong)
{
abc("htonl ");
return 0;
}
char FAR * PASCAL FAR inet_ntoa (struct in_addr in)
{
abc("inet_ntoa ");
return 0;
}
int PASCAL FAR listen (SOCKET s, int backlog)
{
abc("listen ");
return 0;
}
u_long PASCAL FAR ntohl (u_long netlong)
{
abc("ntohl ");
return 0;
}
u_short PASCAL FAR ntohs (u_short netshort)
{
abc("ntohs ");
return 0;
}
int PASCAL FAR recvfrom (SOCKET s, char FAR * buf, int len, int flags,
                         struct sockaddr FAR *from, int FAR * fromlen)
{
abc("recvfrom ");
return 0;
}
int PASCAL FAR select (int nfds, fd_set FAR *readfds, fd_set FAR *writefds,
                       fd_set FAR *exceptfds, const struct timeval FAR *timeout)
{
abc("select ");
return 0;
}
int PASCAL FAR sendto (SOCKET s, const char FAR * buf, int len, int flags,
                       const struct sockaddr FAR *to, int tolen)
{
abc("sendto ");
return 0;
}
int PASCAL FAR shutdown (SOCKET s, int how)
{
abc("shutdown ");
return 0;
}
struct hostent FAR * PASCAL FAR gethostbyaddr(const char FAR * addr,
                               int len, int type)
{
abc("gethostbyaddr");
return 0;
}
struct hostent FAR * PASCAL FAR gethostbyname(const char FAR * name)
{
abc("gethostbyname");
return 0;
}
int PASCAL FAR gethostname (char FAR * name, int namelen)
{
abc("gethostname ");
return 0;
}
struct servent FAR * PASCAL FAR getservbyport(int port, const char FAR * proto)
{
abc("getservbyport");
return 0;
}
struct servent FAR * PASCAL FAR getservbyname(const char FAR * name,
                                              const char FAR * proto)
{
abc("getservbyname");
return 0;
}
struct protoent FAR * PASCAL FAR getprotobynumber(int proto)
{
abc("getprotobynumber");
return 0;
}
struct protoent FAR * PASCAL FAR getprotobyname(const char FAR * name)
{
abc("getprotobyname");
return 0;
}
int PASCAL FAR WSAStartup(WORD wVersionRequired, LPWSADATA lpWSAData)
{
abc("WSAStartup");
sprintf(aa,"wVersionRequired...%u",wVersionRequired);
lpWSAData->wVersion=257;
lpWSAData->wHighVersion=257;
strcpy(lpWSAData->szDescription,"Microsoft Windows Sockets Version 1.1.");
strcpy(lpWSAData->szSystemStatus,"Running on Windows 95.");
lpWSAData->iMaxSockets=256;
lpWSAData->iMaxUdpDg=65467;
lpWSAData->lpVendorInfo=0;
abc(aa);
return 0;
}
int PASCAL FAR WSACleanup(void)
{
abc("WSACleanup");
return 0;
}
void PASCAL FAR WSASetLastError(int iError)
{
abc("WSASetLastError");

}
int PASCAL FAR WSAGetLastError(void)
{
abc("WSAGetLastError");
return 0;
}
BOOL PASCAL FAR WSAIsBlocking(void)
{
abc("WSAIsBlocking");
return 0;
}
int PASCAL FAR WSAUnhookBlockingHook(void)
{
abc("WSAUnhookBlockingHook");
return 0;
}
FARPROC PASCAL FAR WSASetBlockingHook(FARPROC lpBlockFunc)
{
abc("WSASetBlockingHook");
return 0;
}
int PASCAL FAR WSACancelBlockingCall(void)
{
abc("WSACancelBlockingCall");
return 0;
}
HANDLE PASCAL FAR WSAAsyncGetServByName(HWND hWnd, u_int wMsg,
   const char FAR * name,const char FAR * proto,
                                        char FAR * buf, int buflen)
{
abc("WSAAsyncGetServByName");
return 0;
}
HANDLE PASCAL FAR WSAAsyncGetServByPort(HWND hWnd, u_int wMsg, int port,
   const char FAR * proto, char FAR * buf,int buflen)
{
abc("WSAAsyncGetServByPort");
return 0;
}
HANDLE PASCAL FAR WSAAsyncGetProtoByName(HWND hWnd, u_int wMsg,
   const char FAR * name, char FAR * buf,int buflen)
{
abc("WSAAsyncGetProtoByName");
return 0;
}
HANDLE PASCAL FAR WSAAsyncGetProtoByNumber(HWND hWnd, u_int wMsg,
    int number, char FAR * buf,int buflen)
{
abc("WSAAsyncGetProtoByNumber");
return 0;
}
HANDLE PASCAL FAR WSAAsyncGetHostByName(HWND hWnd, u_int wMsg,
  const char FAR * name, char FAR * buf,int buflen)
{
abc("WSAAsyncGetHostByName");
return 0;
}
HANDLE PASCAL FAR WSAAsyncGetHostByAddr(HWND hWnd, u_int wMsg,
  const char FAR * addr, int len, int type,char FAR * buf, int buflen)
{
abc("WSAAsyncGetHostByAddr");
return 0;
}
int PASCAL FAR WSACancelAsyncRequest(HANDLE hAsyncTaskHandle)
{
abc("WSACancelAsyncRequest");
return 0;
}
int PASCAL FAR WSAAsyncSelect(SOCKET s, HWND hWnd, u_int wMsg,
                               long lEvent)
{
abc("WSAAsyncSelect");
return 0;
}
int PASCAL 	__WSAFDIsSet ()
{
abc("__WSAFDIsSet ");
return 0;
}
int PASCAL 	s_perror ()
{
abc("s_perror ");
return 0;
}
int PASCAL 	TransmitFile ()
{
abc("TransmitFile ");
return 0;
}
int PASCAL 	EnumProtocolsA ()
{
abc("EnumProtocolsA ");
return 0;
}
int PASCAL 	EnumProtocolsW ()
{
abc("EnumProtocolsW ");
return 0;
}
int PASCAL 	GetAddressByNameA ()
{
abc("GetAddressByNameA ");
return 0;
}
int PASCAL 	GetAddressByNameW ()
{
abc("GetAddressByNameW ");
return 0;
}
int PASCAL 	GetNameByTypeA  ()
{
abc("GetNameByTypeA  ");
return 0;
}
int PASCAL 	GetNameByTypeW  ()
{
abc("GetNameByTypeW  ");
return 0;
}
int PASCAL 	GetServiceA ()
{
abc("GetServiceA ");
return 0;
}
int PASCAL 	GetServiceW ()
{
abc("GetServiceW ");
return 0;
}
int PASCAL 	GetTypeByNameA ()
{
abc("GetTypeByNameA ");
return 0;
}
int PASCAL 	GetTypeByNameW ()
{
abc("GetTypeByNameW ");
return 0;
}
int PASCAL 	SetServiceA ()
{
abc("SetServiceA ");
return 0;
}
int PASCAL 	SetServiceW  ()
{
abc("SetServiceW  ");
return 0;
}
int PASCAL 	dn_expand ()
{
abc("dn_expand ");
return 0;
}
int PASCAL 	inet_network ()
{
abc("inet_network ");
return 0;
}
int PASCAL 	rexec ()
{
abc("rexec ");
return 0;
}
int PASCAL 	rresvport ()
{
abc("rresvport ");
return 0;
}
int PASCAL WSARecvEx ()
{
abc("WSARecvEx ");
return 0;
}
unsigned long PASCAL FAR inet_addr (const char FAR * cp)
{
    abc("inet_addr ");
    sprintf(aa,"cp..%s",cp);
    abc(aa);
    return 0;
}


u_short PASCAL FAR htons (u_short hostshort)
{
    abc("htons ");
    sprintf(aa,"htons....%u",hostshort);
    abc(aa);
    return 0;
}
SOCKET PASCAL FAR socket (int af, int type, int protocol)
{
    abc("socket ");
    sprintf(aa,"af=%d..type=%d..protocol=%d",af,type,protocol);
      abc(aa);
      return 0;
}


int PASCAL FAR bind (SOCKET s, const struct sockaddr FAR *addr, int namelen)
{
abc("bind ");
return 0;
}

int PASCAL FAR setsockopt (SOCKET s, int level, int optname,const char FAR * optval, int optlen)
{
    abc("setsockopt ");
    sprintf(aa,"level=%d..optname=%d..optval=%s.....optlen=%d",level,optname,optval,optlen);
    abc(aa);
    return 0;
}

int PASCAL FAR recv (SOCKET s, char FAR * buf, int len, int flags)
{
    cnt++;
    abc("recv ");
    sprintf(aa,"buf=%s..len=%d..flags=%d..cnt=%d",buf,len,flags,cnt);
    abc(aa);
    if (cnt == 1)
   {
    memcpy(buf,"HTTP/1.0\r\n\r\n",12);
    return 12;
   }
    else
    if (cnt == 2)
    {
   memcpy(buf,"Hello\r\n",7);
   return 7;
    }

int PASCAL FAR send (SOCKET s, const char FAR * buf, int len, int flags)
{
    abc("send ");
    sprintf(aa,"buf=%s..len=%d..flags=%d",buf,len,flags);
    abc(aa);
    return len;
}


int PASCAL WsControl(void *i1,void *i2,void *i3,void *i4,void *i5,void *i6)
{
abc("WsControl");
return 0;
}
int PASCAL 	NPLoadNameSpaces (void *i1,void *i2,void *i3)
{
abc("NPLoadNameSpaces ");
return 0;
}

z.txt

DllMain
WSAStartup
wVersionRequired...257
socket 
af=2..type=1..protocol=0
setsockopt 
level=65535..optname=4..optval=yes.....optlen=4
gethostname 
gethostbyname
inet_addr 
cp..70.0.0.2
htons 
htons....80
htonl 
socket..0..namelen...16
sa_family = 2.. sa_data = ..0. .namelen=16..
connect 
getsockname 
ntohs 
send 
buf=GET / HTTP/1.0

..len=16..flags=0
send 
buf=User-Agent: JDK/1.0

..len=21..flags=0
send 
buf=Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2

..len=62..flags=0
send 
buf=

cept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2

..len=2..flags=0
recv 
buf=..len=2048..flags=0..cnt=1
recv 
buf=
..len=2036..flags=0..cnt=2
recv 
buf=..len=2029..flags=0..cnt=3
DllMain
WSACleanup
DllMain

After fiddling around with these .dlls, we hope you appreciate the importance of WinSock. For those who are still in shock from seeing Java humbled, I suggest a warm glass of milk, an early night and a C/C++ compiler. Remember, Java is 'Just another Language' and not some technological revolution. As we've just shown, it's extremely simple to dupe Java into believing anything! If you can prove otherwise, write in and joust!


The above tutorial is a joint effort of

Mr. Vijay Mukhi
Ms. Sonal Kotecha
Mr. Arsalan Zaidi
Mr. R. D. Parab


Back to the main page


Vijay Mukhi's Computer Institute
VMCI, B-13, Everest Building, Tardeo, Mumbai 400 034, India
Tel : 91-22-496 4335 /6/7/8/9     Fax : 91-22-307 28 59
e-mail : vmukhi@giasbm01.vsnl.net.in
http://www.vijaymukhi.com