Smart questions
Smart answers
Smart people
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Member Login

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips now!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

Join Tek-Tips
*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

LINK TO THIS FORUM!

Add Stickiness To Your Site By Linking To This Professionally Managed Technical Forum.
Just copy and paste the
code below into your site.

Partner With Us!

"Best Of Breed" Forums Add Stickiness To Your Site
Partner Button
(Download This Button Today!)

Feedback

"...I can't start my day without this site!..."

Geography

Where in the world do Tek-Tips members come from?

Embarcadero: C++Builder FAQ

Socket Programming

How to create a Server Socket
Posted: 15 Aug 01

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.


Back to Embarcadero: C++Builder FAQ Index
Back to Embarcadero: C++Builder Forum

My Archive

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close