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 strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to create a Server Socket

Socket Programming

How to create a Server Socket

by  hnd  Posted    (Edited  )
How do I create a Server Socket?

See also how to Create a a Client Socket.

The difference between a Client Socket and a Server Socket is:
A client Socket does an Aktive Connection.
A Server Socker waits passive for a Connection

The routines below have been tested with Windows NT and the C++-Builder, but special
C++ features are not used.

With small modifications they could be used in Unix environments.

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

//---------------------------------------------------------------------------
#pragma package(smart_init)
/*============================================================
Oeffnen eines Netzwerkknotens als Server
==============================================================*/
#include <winsock.h>
#include <mem.h>
#include <errno.h>
#include <stdio.h>
#include <io.h>

//define Error Return 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
#define SOCKET_BIND_ERROR -7
#define SOCKET_LISTEN_ERROR -8

#define NR_CONNECTIONS 3 // Maximum Number of allowed Connections Max 5
// could be passed to the routine as an Argument too


int tcp_accept(char *service,int port,char *emsg,unsigned int dllhandle)

/***********************************************************************
service Service Name in the Service Table (required if Port = 0)
Port Port Number Required if service = empty
emsg Error Message (char[60] should be enough)
dllhandle Handle to winsock.dll (see netinit in Faq creating a Client socket)
************************************************************************/
{
unsigned long inaddr;
unsigned char hostname[20];
unsigned char buffer[4];
servent *sp;
int is;
hostent *hp;
sockaddr_in tcp_srv_addr;
int fd;

// Define DLL-Functions

struct servent FAR * PASCAL (FAR *gsbyname)(const char FAR* ,const char FAR *);
u_short PASCAL (FAR *htns) (u_short FAR);
struct hostent FAR * PASCAL (FAR *ghbyname)(const char FAR * name);
SOCKET PASCAL (FAR *sckt) (int FAR, int FAR, int FAR);
int PASCAL (FAR *bind) (SOCKET s,const struct sockaddr FAR *, int namelen);
int PASCAL (FAR *lstn) (SOCKET FAR, int backlog);
int PASCAL (FAR *ghsn) (char *, int len);



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

Initialize DLL-Functions

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

(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)ghbyname = GetProcAddress((HINSTANCE)dllhandle,"gethostbyname");
if(ghbyname==NULL)
return DLL_ERROR;
(FARPROC)ghsn = GetProcAddress((HINSTANCE)dllhandle,"gethostname");
if(ghbyname==NULL)
return DLL_ERROR;
(FARPROC)sckt = GetProcAddress((HINSTANCE)dllhandle,"socket");
if(sckt==NULL)
return DLL_ERROR;
(FARPROC)bind = GetProcAddress((HINSTANCE)dllhandle,"bind");
if(bind==NULL)
return DLL_ERROR;
(FARPROC)lstn = GetProcAddress((HINSTANCE)dllhandle,"listen");
if(lstn==NULL)
return DLL_ERROR;
memset(&tcp_srv_addr,0,sizeof(sockaddr_in)) ;

tcp_srv_addr.sin_family=AF_INET;

// 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 MyHost address

(*ghsn)(hostname,20);
hp=(*ghbyname)(hostname);
inaddr =(unsigned long) *hp->h_addr;
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);
is=sizeof(inaddr);
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;
}
// Bind Socket to Address
if((is=(*bind)(fd,(struct sockaddr *) &tcp_srv_addr,sizeof(sockaddr_in)))==SOCKET_ERROR)
{
is=WSAGetLastError();
sprintf(emsg,"tcp_accept: Bind Error=%d\n",is);
return SOCKET_BIND_ERROR;
}

// define Socket as a listener
// NR_Connections gives the maximum allowed # of pending Connections.
// if there are more requests, the connections are refused.

if((is=(*lstn)(fd,NR_CONNECTIONS))==SOCKET_ERROR)
{
is=WSAGetLastError();
sprintf(emsg,"tcp_accept: Listen Error=%d\n",is);
return SOCKET_LISTEN_ERROR;
}
}

return fd;
}

=======================================================================================

this function now can be used in following sequence
sockaddr saddr;
.
.
.

// define Accept function

int PASCAL (FAR *acpt) (SOCKET FAR, struct sockaddr FAR *, int *adrlen);
.
.
.
// Init DLL functions
dllhandle=netinit("c:\\winnt\\system32\\wsock32.dll");
(FARPROC)acpt = GetProcAddress((HINSTANCE)dllhandle,"accept");
if(acpt==NULL)
{
return -1;
}


if((fd=tcp_accept("",PORT,emsg,dllhandle))<0)
{
return fd;
}
// infinite Loop

while(1)
{

buffersize=sizeof(sockaddr);

// wait for a connection
// On this place usually there should be a way to get the IP-Address from the connecting
// host. The array saddr.sa_data[2] contains the IP of the connecting Host
// Create a independent Copy (fd1) of Socket fd
le = sizeof(saddr)
if((fd1=(*acpt)(fd,saddr,&le))>0)
{
// If connection is ok create a new thread and pass handle fd1 to the the server function(netserver)
// in this function everything is handled. Don't forget to close all sockets after use
ih=(unsigned long *)CreateThread(NULL,0,netserver,fd1,0,&serverid);
}
// You can use the Handle fd1 like it is used on a Client Socket.
}
return 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 a 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