CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 3 of 3
  1. #1
    Join Date
    Mar 1999
    Posts
    4

    Writing a server program using VC++



    Hello everyone,


    I am planning to write a server program using VC++.


    Which project type should I use? I want to use MFC

    but since it is a server program, it does not need to have any gui.

    Also, it must be able to spin off multiple threads.


    The server is going to use CSocket to communicate with its

    clients. Is there a better way?


    Or is there a skeleton main program of a server programs which

    accepts a connection and does something?


    In short, I have experience writing VC++ GUI program but have not done

    any server program development. I just want to get started in the right

    direction.


    Please advise. Thanks a lot!


    regards,

    roger

  2. #2
    Join Date
    Apr 1999
    Location
    NY
    Posts
    4

    Re: Writing a server program using VC++



    Check Out The "System" section on the CodeGuru Home Page.

    I saw some examples and discussion there.


    Hope It Helps.

  3. #3
    Join Date
    Apr 1999
    Posts
    4

    RE: Writing a server program using VC++

    I should use the win32 console application, and write the whole app in posix c++, has great adventage that it is multi-platform. You know exactly what's going on, think that is important in a server app. If a gui app has a memory leak, so what, but a server app, it keeps grewing cause it should run for ever ( well the uptime of NT is not that high...)

    Have some source for socket btw... under windoze u must link a certain file with it.. (is named in documentation.. look for accept or something like that... )

    !!! Using this file as example is fine, when modifing, copying etc... u must return it in public
    !!! and the names of the authors stay in the files

    /* File: Socket.h
    Author: RA Scheltema
    E Witteveen
    [email protected]
    Date: Januari 8, 1999

    Implementation of the java socket-class
    in C++ .


    ToDo:
    - Think about m_connected.
    - In constructor clean up yer stuff on error.
    - write(void *bytes)
    Send bytes that where left over after first send.
    - read(int &length)
    Send bytes that where left over after first send.
    */

    #ifndef _SOCKET_CLASS_
    #define _SOCKET_CLASS_

    #ifdef LINUX
    typedef int SOCKET;
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <unistd.h>
    #include <errno.h>
    #else // WINDOWS
    #include <winsock.h>
    typedef SOCKADDR_IN sockaddr_in;
    #endif
    #include <iostream.h>
    #include "Exception.h"
    #include "InetAddress.h"

    #define BLOCKSIZE 1024

    typedef enum {
    ftp = 21, //tcp
    telnet = 23, //tcp
    smtp = 25, //tcp mail
    time_ = 37, //tcp timeserver # name conflict with afx.h & time.h
    name = 42, //tcp nameserver
    nameserver = 53, //tcp domain # name-domain server
    finger = 79, //tcp
    http = 80, //tcp
    pop = 109, //tcp postoffice
    pop2 = 109, //tcp # Post Office
    pop3 = 110, //tcp postoffice
    nntp = 119 //tcp usenet # Network News Transfer
    } SocketService;


    class Socket {
    public:
    Socket();
    // Makes an unconnected socket-instance.
    // Socket(unsigned long int port) throw(Exception);
    // Makes a socket-instance on localhost and port.
    Socket(TString adress, unsigned short int port) throw(Exception);
    // Makes a socket-instance on host and port.
    ~Socket();

    void disconnect();
    int available() throw(Exception);
    // Returns the number of bytes on the socket, without blocking.

    void write(void *bytes, size_t length) throw(Exception);
    void *read(int &length) throw(Exception);


    public:
    SOCKET m_socket;


    protected:
    #ifdef LINUX
    #else // WINDOWS
    #endif
    struct sockaddr_in m_address;
    };


    #endif


    ////// next file is socket.cpp
    include "Socket.h"

    /// [email protected]

    Socket::Socket() {
    m_socket = -1;
    }
    /*
    Socket::Socket(unsigned long int port) throw(Exception) {
    #ifdef LINUX
    Socket(InetAdress(LocalHost), port);
    #else // WINDOWS
    #endif
    }
    */
    Socket::Socket(TString address, unsigned short int port) throw(Exception) {
    #ifdef LINUX
    m_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (m_socket < 0) {
    if(errno == EACCES)
    throw(EXCEPTION("Permission to create a socket is denied."));
    else if(errno == ENOBUFS)
    throw(EXCEPTION("Insufficient number of recourses free to create a socket."));
    else
    throw(EXCEPTION("General failure to create a socket."));
    }

    memset(&m_address, 0, sizeof(struct sockaddr_in));
    m_address.sin_family = AF_INET;
    memcpy(&m_address.sin_addr.s_addr,
    address.getAddress()->h_addr,
    address.getAddress()->h_length);
    m_address.sin_port = htons(port);
    if (connect(m_socket,(struct sockaddr*) &m_address, sizeof(struct sockaddr_in)) == -1) {
    disconnect(); // Does not work.
    close(m_socket);
    if (errno == ECONNREFUSED)
    throw(EXCEPTION("Could not connect, due to refuse of server."));
    else if (errno == ETIMEDOUT)
    throw(EXCEPTION("Didn't connect, due to timeout."));
    else if (errno == EADDRINUSE)
    throw(EXCEPTION("Didn't connect, because address is allready in use."));
    else
    throw(EXCEPTION("Didn't connect, due to a general failure."));
    }
    #else // WINDOWS
    const WORD wMinVer = 0x0101; // request WinSock v1.1 (at least)
    WSADATA wsaData;

    if(WSAStartup(wMinVer, &wsaData) != 0)
    throw(EXCEPTION("Error in constructing Socket: got request for WinSock < v1.1."));

    m_socket = socket(PF_INET, SOCK_STREAM, 0);
    if (m_socket == INVALID_SOCKET) {
    // int error = WSAGetLastError();
    throw(EXCEPTION("could not create socket."));
    }

    m_address.sin_family = AF_INET ;
    // m_address.sin_addr.S_un.S_addr = *(unsigned long *)(address.getA()->h_addr_list[0]);
    char *www = address.toChar();
    m_address.sin_addr.S_un.S_addr = inet_addr(www);
    delete[] www;
    m_address.sin_port = htons(port);
    if( SOCKET_ERROR == ::connect(m_socket, (sockaddr *)&m_address, sizeof(struct sockaddr_in))) {
    // int error = WSAGetLastErro();
    throw(EXCEPTION("Connection error."));
    }
    #endif
    }

    Socket::~Socket() {
    disconnect();
    }

    void Socket:isconnect() {
    shutdown(m_socket, 2);
    #ifdef LINUX
    close(m_socket);
    #else // WINDOWS
    closesocket(m_socket);
    #endif
    }

    int Socket::available() throw(Exception) {
    int recieved,
    buf_size = BLOCKSIZE;
    char *buf = new char[buf_size];

    #ifdef LINUX
    while ((recieved = recv(m_socket, buf, buf_size, MSG_PEEK)) == buf_size) {
    #else // WINDOWS
    while ((recieved = ::recv(m_socket, buf, buf_size, MSG_PEEK)) == buf_size) {
    #endif
    delete[] buf;
    buf_size += BLOCKSIZE;
    buf = new char[buf_size];
    }

    delete[] buf;
    if (recieved == -1)
    throw(EXCEPTION("General failure in determening size of data on the socket."));
    else
    return recieved;
    }

    void Socket::write(void *bytes, size_t length) throw(Exception) {
    #ifdef LINUX
    int nr_send = send(m_socket, bytes, length, 0);
    if (nr_send == -1) {
    if (errno == ENOBUFS)
    throw(EXCEPTION("Could not send data, because of congestion of the output queue of the network interface."));
    else if (errno == EFAULT)
    throw(EXCEPTION("Could not send data, because of invalid data."));
    else
    throw(EXCEPTION("Could not send data, because of general failure."));
    }

    /* If not all bytes where send, send the rest.
    */
    #else // WINDOWS
    int nr_send = ::send(m_socket, (char FAR*) bytes, length, 0);
    if (nr_send == -1) {
    //int error = WSAGetLastError();
    throw(EXCEPTION("Could not send data, because of general failure."));
    }

    /* If not all bytes where send, send the rest.
    */
    #endif
    }

    void *Socket::read(int &length) throw(Exception) {
    length = available();
    void *bytes = malloc(length);
    if (bytes == NULL)
    throw(EXCEPTION("Could not read, because no memory could be allocated."));

    #ifdef LINUX
    int nr_recieved = recv(m_socket, bytes, length, 0);
    if (nr_recieved == -1) {
    free(bytes);
    if (errno == EINTR)
    throw(EXCEPTION("Could not read, because of interrupt."));
    else
    throw(EXCEPTION("Could not read, because of general failure."));
    }

    /* If not all bytes where read, read the rest.
    */
    #else
    int nr_recieved = ::recv(m_socket, (char FAR*) bytes, length, 0);
    if (nr_recieved == -1) {
    //int error = WSAGetLastError();
    throw(EXCEPTION("Could not read, because of general failure."));
    }

    /* If not all bytes where read, read the rest.
    */
    #endif

    return (void *)bytes;
    }

    //////next file is serversocket.h
    /* Class: ServerSocket
    Author: RA Scheltema
    E Witteveen
    [email protected]
    Date: Januari 9, 1999

    Implementation of Java's ServerSocket in
    C++ .


    ToDo:
    - In constructor clean up yer stuff on error.
    */


    #ifndef _SERVERSOCKET_CLASS_
    #define _SERVERSOCKET_CLASS_

    #ifdef LINUX
    typedef int SOCKET;
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <unistd.h>
    #else // WINDOWS
    #include <winsock.h>
    typedef SOCKADDR_IN sockaddr_in;
    #endif

    #include "Socket.h"

    #define NORMAL_BACKLOG 50


    class ServerSocket {
    public:
    ServerSocket(unsigned short port, unsigned int backLog = 50) throw(Exception);
    ~ServerSocket();

    Socket *_accept() throw(Exception);
    void disconnect();


    private:
    SOCKET m_socket;
    struct sockaddr_in m_address;
    int m_backLog;
    };

    #endif
    ///////next file is serversocket.cpp
    #include "ServerSocket.h"



    ServerSocket::ServerSocket(unsigned short port, unsigned int backLog) throw(Exception) {
    #ifdef LINUX
    m_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (m_socket < 0) {
    if(errno == EACCES)
    throw(EXCEPTION("Permission to create a socket is denied."));
    else if(errno == ENOBUFS)
    throw(EXCEPTION("Insufficient number of recourses free to create a socket."));
    else
    throw(EXCEPTION("General failure to create a socket."));
    }

    memset(&m_address, 0, sizeof(struct sockaddr_in));
    m_address.sin_family = AF_INET;
    m_address.sin_addr.s_addr = htons(INADDR_ANY);
    m_address.sin_port = htons(port);
    if (bind(m_socket, (struct sockaddr *) &m_address, sizeof m_address) == -1) {
    close(m_socket);
    if (errno == EACCES)
    throw(EXCEPTION("Permission to bind to the given adress is denied."));
    else
    throw(EXCEPTION("General failure in binding socket."));
    }

    if (listen(m_socket, backLog) == -1) {
    disconnect(); // Does not work !!!!
    close(m_socket);
    throw(EXCEPTION("General failure in creating socket."));
    }
    #else // WINDOWS
    const WORD wMinVer = 0x0101; // request WinSock v1.1 (at least)
    WSADATA wsaData;

    if(WSAStartup(wMinVer, &wsaData) != 0)
    throw(EXCEPTION("Error in constructing Socket: got request for WinSock < v1.1."));

    m_socket = socket(PF_INET, SOCK_STREAM, 0);
    if (m_socket == INVALID_SOCKET) {
    disconnect();
    // int error = WSAGetLastError();
    throw(EXCEPTION("could not create socket."));
    }

    m_address.sin_family = AF_INET ;
    m_address.sin_addr.S_un.S_addr = htons(INADDR_ANY);
    m_address.sin_port = htons(port);
    if(SOCKET_ERROR == ::bind(m_socket, (sockaddr *)&m_address, sizeof(struct sockaddr_in))) {
    disconnect();
    // int error = WSAGetLastErro();
    throw(EXCEPTION("Connection error."));
    }

    if (::listen(m_socket, backLog) == SOCKET_ERROR) {
    disconnect(); // Does not work !!!!
    throw(EXCEPTION("General failure in creating socket."));
    }
    #endif
    }

    ServerSocket::~ServerSocket() {
    disconnect();
    }


    Socket *ServerSocket::_accept() throw(Exception) {
    SOCKET socket;
    struct sockaddr_in client;
    int client_len = sizeof(sockaddr_in);

    #ifdef LINUX
    socket = accept(m_socket, (struct sockaddr *) &client, &client_len);
    if (socket == -1)
    throw(EXCEPTION("General failure in accepting connection"));
    #else // WINDOWS
    socket = ::accept(m_socket, (struct sockaddr *) &client, &client_len);
    if (socket == SOCKET_ERROR) {
    //int error = WSAGetLastError();
    throw(EXCEPTION("General failure in accepting connection"));
    }
    #endif
    else {
    Socket *s = new Socket();
    s->m_socket = socket;
    return s;
    }
    }

    void ServerSocket:isconnect() {
    #ifdef LINUX
    close(m_socket);
    #else // WINDOWS
    closesocket(m_socket);
    #endif
    }

    /*
    void main() {
    try {
    ServerSocket server(4000);
    }
    catch(Exception e) {
    cout<<e.getMessage()<<endl<<flush;
    }
    }
    */



Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured