Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How do I create a client Socket?

Socket Programming

How do I create a client Socket?

by  hnd  Posted    (Edited  )
This FAQ describes the Creation of a Client socket. The Functions had been tested with C-Builder and Windows NT, but it should work with WIN 9X too. The presence of winsock.dll is required.

With some small modifications it works in a UNIX environment too.

The required routines are encapsulated in the winsock-Dll

The procedure follows following Way.

1. Inititialize Winsock-DLL Handle (function netinit)

2. Create client socket (function tcp_open)
===========================================================

Netinit:

#include <windows.h>
#include <winbase.h>

#define UINT unsigned long
// dllfile = name of winsock-DLL
UINT netinit(char *dllfile)
{
UINT handle;

// DLL-Startup routine

int pascal (FAR *wsastartup)(WORD FAR, LPWSADATA FAR);
WSADATA wsadata;

//DLL-Load
handle = (UINT)LoadLibrary(dllfile);
// if Load was Ok.
if(handle>(UINT) HINSTANCE_ERROR)
{
(FARPROC)wsastartup = GetProcAddress((HINSTANCE)handle,"WSAStartup");
// Is it correct DLL
if(wsastartup!=NULL)
(*wsastartup)(0x0101,&wsadata);
else
// if wrong dll (wrong revision) return 0
return 0;
//otherwise return handle to DLL
return handle;
}

return 0;
}
===========================================================
TCP_Open:

/*******************************************************************

Modul Name: tcp_open.c

Titel: Open a Socket as a Client


*********************************************************************/
/*============================================================
Oeffnen eines Netzwerkknotens
==============================================================*/

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <winsock2.h>
#include <mem.h>
#include <errno.h>
#include <stdio.h>
#include <io.h>

// Define Error Codes =================

#define DLL_ERROR -1
#define UNKNOWN_SERVICE -2
#define SERVICE_MISSING -3
#define UNKNOWN_HOST -4
#define CONNECT_ERROR -5
#define SOCKET_CREATE_ERROR -6
//======================================

int tcp_open(char *host,char *service,int port,char *emsg,unsigned int dllhandle)

/***********************************************************
host : Target-Hostname or IP-Address
service : Portname required if Port = 0
port : Port number required if service=empty
emsg : Errormessages char[60] should be enough
dllhandle: Handle to winsock DLL (result from netinit)
***********************************************************/
{
unsigned long int inaddr;
servent *sp;
int is;
hostent *hp;
u_long iadr;
sockaddr_in tcp_srv_addr;
int fd;
unsigned char hostname[20],buffer[4];
struct servent FAR * PASCAL (FAR *gsbyname)(const char FAR* ,const char FAR *);
u_short PASCAL (FAR *htns) (u_short FAR);
u_long PASCAL (FAR *htnl) (u_long FAR);
struct hostent FAR * PASCAL (FAR *ghbyname)(const char FAR * name);
SOCKET PASCAL (FAR *sckt) (int FAR, int FAR, int FAR);
int PASCAL (FAR *conct) (SOCKET FAR, const struct sockaddr FAR *, int namelen);



/*============================================================

Init phase

===========================================================*/

// Define DLL Procedures
(FARPROC)gsbyname = GetProcAddress((HINSTANCE)dllhandle,"getservbyname");
if(gsbyname==NULL)
return DLL_ERROR;
(FARPROC)htns = GetProcAddress((HINSTANCE)dllhandle,"htons");
if(htns==NULL)
return DLL_ERROR;
(FARPROC)htnl = GetProcAddress((HINSTANCE)dllhandle,"htonl");
if(htnl==NULL)
return DLL_ERROR;
(FARPROC)ghbyname = GetProcAddress((HINSTANCE)dllhandle,"gethostbyname");
if(ghbyname==NULL)
return DLL_ERROR;
(FARPROC)sckt = GetProcAddress((HINSTANCE)dllhandle,"socket");
if(sckt==NULL)
return DLL_ERROR;
(FARPROC)conct = GetProcAddress((HINSTANCE)dllhandle,"connect");
if(conct==NULL)
return DLL_ERROR;

// Clear tcp Buffer

_fmemset(&tcp_srv_addr,0,sizeof(tcp_srv_addr)) ;
tcp_srv_addr.sin_family=AF_INET;
/*============================================================
Get port number from service Table
============================================================*/
// if there is a Service Table to be used
if(*service != 0)
{
// is there a Service Entry
if((sp = (*gsbyname)(service,"tcp")) == NULL)
{
sprintf(emsg,"tcp_open: unknown service: %s /tcp\n",service);
return UNKNOWN_SERVICE;
}

// Setup Structure for socket

if(port>0)
{
tcp_srv_addr.sin_port=(*htns)(port);
}
else
{
tcp_srv_addr.sin_port=sp->s_port;
}
}
else

// If there is a Service number

{
if(port<=0)
{
sprintf(emsg,"tcp_open: must specify either service or port\n");
return SERVICE_MISSING;
}
tcp_srv_addr.sin_port=(*htns)(port);
}
// Check Host address
if((inaddr = inet_addr(host)) != INADDR_NONE)
{
memmove((char *)&tcp_srv_addr.sin_addr,(char *) &inaddr,sizeof(inaddr));
}
else

// if host name used get host data from Tables

{
if((hp=(*ghbyname)(host)) == NULL)
{
sprintf(emsg,"tcp_open: Host Name Error: %s\n",host);
return UNKNOWN_HOST;
}
buffer[0]=*hp->h_addr++ ;
buffer[1]=*hp->h_addr++ ;
buffer[2]=*hp->h_addr++ ;
buffer[3]=*hp->h_addr++ ;
sprintf(hostname,"%d.%d.%d.%d\0",buffer[0],buffer[1],buffer[2],buffer[3]);
inaddr=inet_addr(hostname);

// Copy data into structure
iadr=(*htonl)((u_long)*hp->h_addr);
memmove(&tcp_srv_addr.sin_addr,&inaddr,sizeof(inaddr));
}

// Create Networksocket(AF_INET)

if (port>=0)
{
if((fd=(*sckt)(AF_INET,SOCK_STREAM,0))==SOCKET_ERROR)
{
is=(int)errno;
sprintf(emsg,"tcp_open: can't create TCP socket fd=%d\n",fd);
return SOCKET_CREATE_ERROR;
}
}

// connect socket to Host

if(((*conct)(fd,(struct sockaddr *) &tcp_srv_addr,sizeof(tcp_srv_addr)))<0)
{
sprintf(emsg,"tcp_open: can't connect to server\n");
close(fd);
return CONNECT_ERROR;
}

// everything ok. Now you can use fd as an regular
// file descriptor(netread/netwrite(fd,&value,sizeof(value)).....
return fd;
}
============================================================
Probably The functions netread and netwrite have to be modified dependent on appliction

These are Examples for ASCII transmission with <CR> as Terminator.



function netread:

//reads from an Socket

#include <vcl.h>
#pragma hdrstop
#include <winsock2.h>
#define DLL_ERROR -1
#define NRCYCLES 100

int netread(int sock,void *val,const int le,int netdll)
/**********************************************************

sock : Socket created by tcp_open or accept funtion in case of a Server Socket
val : readbuffer
le : length of readbuffer
netdll : Handle to winsock Dll

Netread returns the number of bytes read

***********************************************************/
{
int nrbytes,cnt,retcode;
int PASCAL (FAR *rcv) (SOCKET FAR, char FAR *, int FAR, int FAR);
char *p,*p1;
//===================================================================
// Initialize dll function

(FARPROC)rcv = GetProcAddress((HINSTANCE)netdll,"recv");
if(rcv==NULL) return DLL_ERROR;

nrbytes=0;
cnt=NRCYCLES;
// p = pointer to receive buffer
p=(char *)val;
do
{
retcode=(*rcv)(sock,p,le,0);
if(retcode==SOCKET_ERROR)
{
return -1;
}
else
{
p1=p;

p +=retcode;
nrbytes +=retcode;
// did a carriage return arrive? yes then terminate
if(*p1==13)
*p1=0;
}
}
// Repeat until buffer full or there is no transfer
// active for NCYCLE rounds or transfer terminated
while((nrbytes<le)&&(cnt-->0)&&(*p1!=0));
return nrbytes;
}
===========================================================


// netwrite
// writes to a network socket

#include <vcl.h>
#pragma hdrstop
#include <winsock2.h>
#define DLL_ERROR -1

int netwrite(int sock,void *val,const int le,int netdll)

// definitions : see netread

{
int PASCAL (FAR *snd) (SOCKET FAR, char FAR *, int FAR, int FAR);

//===================================================================
// Initialisierung

(FARPROC)snd = GetProcAddress((HINSTANCE)netdll,"send");
if(snd==NULL) return DLL_ERROR;
return (*snd)(sock,(char*)val,le,0);
}
//==========================================================

Don't forget to close the socket after use by closesocket.
Closesocket is encapsulated in winsock.dll.

It is called:

CloseSocket(fd); where fd is handle to the Socket (int)

The initilization is equivalent to the other winsock-functions.



Register to rate this FAQ  : BAD 1 2 3 4 5 6 7 8 9 10 GOOD
Please Note: 1 is Bad, 10 is Good :-)

Part and Inventory Search

Back
Top