listening to a port on the local host

hi

i developing a code that listens to a port on the local host and keeps listening until a data arrives from anywhere to that port, then a i process that data, send an acknowledgment to the sender and then go back listening to the same port.

is there is any ready made code or sample to do this, what i did was using ASP code which is not effecient at all. So i deceided to develope it in C++.

regards,
sultan666Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

sultan666Author Commented:
yes but how would this work?

i need a program that receives a string from the client and then sends the ACK string.
0
skypalaeCommented:
Hi,

the answer is 'socket'. There are good resources on socket programming. They may differ a little on MSWin, UNIX, or JAVA platforms, but generally they are all the same.

first make a socket. bind a port to it. listen and wait.
when a connection arrives, create new socket accepting the connection and
    1, do your communication, calculations and at the and close the socket. this would be simplest, but it wouldn't allow other to connect to your machine during process
    2, make new thread somehow and process the communication and calculations while listening to more new connections. this is bit more complex and hard to write, but you can accept as many connections anytime it is wanted. don't forget to close all sockets at the end.

Check out this page. What you want is written under 'Server applications'
http://www.uwo.ca/its/doc/courses/notes/socket/

S.
0
Cloud Class® Course: Microsoft Exchange Server

The MCTS: Microsoft Exchange Server 2010 certification validates your skills in supporting the maintenance and administration of the Exchange servers in an enterprise environment. Learn everything you need to know with this course.

skypalaeCommented:
Reieving a string from client and sending a string is done these ways (this is part of my code, it is server/client application. it connects to a server and waits for connection from a client. than it just passes the data through and does some more calculations on them):

unsigned buf_length = 0 ;
char buf [1024] ;

.
.

case WM_SOCKET2_NOTIFY:
    switch (WSAGETSELECTEVENT (lParam)) {
    case FD_READ:
        buf_length = recv (s2, buf, 1024, 0) ;
        send (s1, buf, buf_length, 0) ;
.
.
.
    }
    return TRUE ;
0
sultan666Author Commented:
actually i have only one client which connects to my server, this application is specific to that client. so it wouldnt make any differrence.

but i need to put all the code in one single project in the MFC how is this possible or do you have a sample code for listening to the port then waiting for a connection if the connection is made then the processing happens and then i send an ACK then go back and listen.

0
sultan666Author Commented:
i have tried many code offered by the links you have supplied but it still doesnt make sense or it is made for other applications, or gave many errors. there must be something simple and neat.

0
skypalaeCommented:
yes, i have some examples. but they are Win32, not MFC. Anyway, i'll post something (i assume you know something about programming Win32, so i'll not explain registering window classes, writing window procs and processing events, you can find these on the web)


static SOCKET s1, s2, tmp_s ;
struct sockaddr_in sa1, sa2 ;

static unsigned buf_length = 0 ;
static char buf [1024] ;

WSADATA wsaData ;

switch (nMessage) {
case WM_CREATE:
            
      WSAStartup (2, &wsaData) ;

      if ((tmp_s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) != INVALID_SOCKET) {
            if (WSAAsyncSelect (tmp_s, hWnd, WM_SOCKETTMP_NOTIFY, FD_ALL_EVENTS) == SOCKET_ERROR)
                  DestroyWindow (hWnd) ;

            sa2.sin_family = AF_INET ;
            sa2.sin_port = htons (23) ; // this is standard telnet port
            sa2.sin_addr.S_un.S_addr = *(unsigned *)* gethostbyname ("localhost")->h_addr_list ;

            bind (tmp_s, (SOCKADDR *)&sa2, sizeof (sa2)) ;
            listen (tmp_s, 1) ;
      }

      return TRUE ;

case WM_DESTROY :
      closesocket (s1) ;
      closesocket (s2) ;
      WSACleanup () ;
      return TRUE ;

case WM_SOCKETTMP_NOTIFY:
      switch (WSAGETSELECTEVENT (lParam)) {
      case FD_ACCEPT:
            s2 = accept (tmp_s, NULL, NULL) ;
            if (WSAAsyncSelect (s2, hWnd, WM_SOCKET2_NOTIFY, FD_ALL_EVENTS) == SOCKET_ERROR)
                  DestroyWindow (hWnd) ;
            closesocket (tmp_s) ;

            if ((s1 = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) != INVALID_SOCKET) {

                  sa1.sin_family = AF_INET ;
                  sa1.sin_port = htons (23) ;
                  sa1.sin_addr.S_un.S_addr = *(unsigned *)* gethostbyname ("sometelnet.com")->h_addr_list ;

                  connect (s1, (SOCKADDR *)&sa1, sizeof (sa1)) ;

                  if (WSAAsyncSelect (s1, hWnd, WM_SOCKET1_NOTIFY, FD_ALL_EVENTS) == SOCKET_ERROR)
                        DestroyWindow (hWnd) ;
            }

      }
      return TRUE ;

case WM_SOCKET1_NOTIFY:
      switch (WSAGETSELECTEVENT (lParam)) {
      case FD_READ:
            buf_length = recv (s1, buf, 1024, 0) ;
            send (s2, buf, buf_length, 0) ;
            break;
      case FD_CLOSE:
            DestroyWindow (GetParent (hWnd)) ;
            break ;
      }

      return TRUE ;

case WM_SOCKET2_NOTIFY:
      switch (WSAGETSELECTEVENT (lParam)) {
      case FD_READ:
            comm_buf_length = recv (s2, comm_buf, 1024, 0) ;
            send (s1, comm_buf, comm_buf_length, 0) ;
      }

      return TRUE ;

default:
      return DefWindowProc (hWnd, nMessage, wParam, lParam) ;
}



Here you seel almost all of my code. As i explained. First I open tmp_socket and wait for a connection. The coonection arrives with WM_SOCKETTMP_NOTIFY message. Here i accept the connection and make a new one (the client part .. no need to wait for anything) and then in client or server notifies i just pass the data to the other socket.

S.
0
sultan666Author Commented:
i have used MVC and started a new project win32 console appliction in simple format, i have paste your code but it came up with about 77 errors. it would be really helpfull if you supply me with one page peive of code to paste it in MVC so tha i compile it and run it.

thank you,
0
sultan666Author Commented:
i have used before the following code and it works fine but with file transfer not with string transfer, is it possible to send and receive strings instead of file transfer.

Also this code doesnt go back and listen after processing requests.

************************************************************************************

// asdfsd.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "asdfsd.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// The one and only application object

CWinApp theApp;

using namespace std;
#define PORT 1890
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
      int nRetCode = 0;

      // initialize MFC and print and error on failure
      if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
      {
            // TODO: change error code to suit your needs
            cerr << _T("Fatal Error: MFC initialization failed") << endl;
            nRetCode = 1;
      }
      else
      {
            AfxSocketInit(NULL);
            CSocket sockSrvr;
            sockSrvr.Create(PORT);
            sockSrvr.Listen();
            CSocket sockRecv;
            sockSrvr.Accept(sockRecv);


            CFile myFile;
            myFile.Open("C:\\CLDMA.LOG", CFile::modeRead | CFile::typeBinary);

            int myFileLength = myFile.GetLength();

            sockRecv.Send(&myFileLength, 4);
            
            byte* data = new byte[myFileLength];

            myFile.Read(data, myFileLength);

            sockRecv.Send(data, myFileLength);

            myFile.Close();
            delete data;

            sockRecv.Close();




      }

      return nRetCode;
}
0
skypalaeCommented:
my whole app is too long to post it all, and i have no time to write some kind of minimal working app.
but your file-transfer code is exactly what you need. only change these lines:

int myFileLength = ...
...
...
delete [] data ;

into

//////
CString str = "Whatever string you want to send" ;
int len = str.GetLength ();

sockRecv.Send (&len, sizeof (int)) ;
sockRecv.Send ((LPCTSTR)str, len) ;
//////

if you want to learn bit more on winsock programming try google or altavista. there are many code examples on the internet
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
sultan666Author Commented:
its not clear what to replace in my code, what do u mean?

also the code you have mentioned is only for sending a string but what about receiving from client once connected.

regards,
0
sultan666Author Commented:
would this work????


am i making sense?




else
      {
            AfxSocketInit(NULL);
            CSocket sockSrvr;
            sockSrvr.Create(PORT);
            sockSrvr.Listen();
            CSocket sockRecv;
            sockSrvr.Accept(sockRecv);

//////
CString str;
int len;

sockRecv.Receive ((LPCTSTR)str, len) ;

            

//////
CString str = "Whatever string you want to send" ;
int len = str.GetLength ();

sockRecv.Send (&len, sizeof (int)) ;
sockRecv.Send ((LPCTSTR)str, len) ;
//////

            
            sockRecv.Close();




      }

      return nRetCode;
}
0
sultan666Author Commented:
i got this error when i ran the previous code


C:\Inetpub\wwwroot\login\mfc\Server\asdfsd.cpp(44) : error C2664: 'Receive' : cannot convert parameter 1 from 'const char *' to 'void *'
0
skypalaeCommented:
ok, ok, ok.

i've written the simplest server/client app i could imagine. just open VC++ twice, create 2 workspaces, 2 projects (1 called client, 1 called server), paste the sources there and run them (server first). they're both console apps, so you can bring both consoles to the front, and watch the result.

///// server /////
#pragma comment(lib, "ws2_32.lib")
#include <winsock2.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char* argv[]) {

      SOCKET s, tmp_s ;
      struct sockaddr_in sa ;

      char buf [1024] = "" ;

      WSADATA wsaData ;
      WSAStartup (2, &wsaData) ;

      if ((tmp_s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
            return -1 ;

      sa.sin_family = AF_INET ;
      sa.sin_port = htons (1234) ;
      sa.sin_addr.S_un.S_addr = *(unsigned *)* gethostbyname ("localhost")->h_addr_list ;

      bind (tmp_s, (SOCKADDR *)&sa, sizeof (sa)) ;
      listen (tmp_s, 1) ;
      s = accept (tmp_s, NULL, NULL) ;
      closesocket (tmp_s) ;

      while (1) {
            if (recv (s, buf, 1024, 0) == SOCKET_ERROR)
                  break ;
            printf ("recieved '%s' : ", buf) ;
            strrev (buf) ;
            printf ("sending '%s' \n", buf) ;
            send (s, buf, strlen(buf), 0) ;
      }

      closesocket (s) ;
      WSACleanup () ;

      return 0;
}
//// end of server ////


///// client /////
#pragma comment(lib, "ws2_32.lib")
#include <winsock2.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char* argv[]) {

      SOCKET s ;
      struct sockaddr_in sa ;

      char buf [1024] = "" ;

      WSADATA wsaData ;
      WSAStartup (2, &wsaData) ;

      if ((s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
            return -1 ;

      sa.sin_family = AF_INET ;
      sa.sin_port = htons (1234) ;
      sa.sin_addr.S_un.S_addr = *(unsigned *)* gethostbyname ("localhost")->h_addr_list ;

      connect (s, (SOCKADDR *)&sa, sizeof (sa)) ;

      printf ("Type some chars:\n") ;
      while (1) {
            scanf ("%s", buf) ;
            send (s, buf, strlen(buf), 0) ;
            if (recv (s, buf, 1024, 0) == SOCKET_ERROR)
                  break ;
            printf ("%s\n", buf) ;
      }

      closesocket (s) ;
      WSACleanup () ;

      return 0;
}
//// end of client ////

the communication part is inside the while(1) loop. it works one by one (one send, one recieve).

S.
0
skypalaeCommented:
one more ... that #pragma in the begining is for i don't include ws2_32.lib in my project library list. it works the same and it eliminates those "unresolved symbol" messages during linking.
S.
0
sultan666Author Commented:
thank you a solved using the previously mentioned changes to my code, you were really helpful.

i will now try to insert the received data into SQL server database table.

any idea how to do this?
0
skypalaeCommented:
i've done some sql using MS-ADO, but i don't know if this is what you need. i met several problems using ADO.

1: How to create an empty database? Not making a DB in Access, but to make the whole new DB from scratch.
SQLConfigDataSource (NULL, ODBC_ADD_DSN, "Microsoft Access Driver (*.mdb)", "CREATE_DB=MyDatabase.mdb") ;

2: What to do next? How to create tables, rows etc...?
Use standard SQL commands on CDatabase object.
CDatabase db ;
db.ExecuteSQL ("CREATE TABLE my_table (my_field integer);") ;
db.ExecuteSQL ("INSERT INTO my_table VALUES (1);") ;

3: and how to access them?
Standard SQL again, now used on CRecordset objects.


0
sultan666Author Commented:
actualy i have the tables ready in the database i just need to insert a record in one table and thats it.

but i need the code for connecting to the database then inserting the record.

thank you.
0
skypalaeCommented:
following should be enough. if you want more, check MSDN or internet. Everything is SQL based, so you have to know how to create valid SQL statement (you have to have MS ODBC drivers installed too .. but i suppose you have those, since you mentioned you have MS Access).

/// create dbase
CDatabase db ;
db.OpenEx OpenEx ("DriverMicrosoft Access Driver (*.mdb);Dbq=MyDatabase.mdb;") ;
db.ExecuteSQL ("CREATE TABLE ......") ;
db.ExecuteSQL ("INSERT INTO ......") ;


// create query
CRecordset rs (&db) ;
rs.Open (AFX_DB_USE_DEFAULT_TYPE, "SELECT whatever FROM whatever", CRecordset::readOnly) ;


// read query
CDBVariant varVal ;
for (rs.MoveFirst(); !rs.IsEOF(); rs.MoveNext()) {
    rs.GetFieldValue ("fieldname", varVal) ;
    myIntegerValue = varVal.m_lVal ;
}
0
sultan666Author Commented:
the data base am using is not acess its SQL 2000 server how does that impact the code you previously mentioned.

thank you again
0
skypalaeCommented:
well, as far as i know only the ODBC driver should be different (that's the string "DriverMicrosoft Access Driver (*.mdb)") but i never tried it, so i dont know how anf if it works. the rest of the code should be exactly same i wrote.

try webpage http://www.microsoft.com/data and from there 'technical articles', 'ODBC', 'Using ODBC with MS SQL Server'. you should find all information needed.

S.
0
sultan666Author Commented:
thank you
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Software

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.