Solved

listening to a port on the local host

Posted on 2003-11-30
22
563 Views
Last Modified: 2013-11-15
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,
0
Comment
Question by:sultan666
  • 12
  • 9
22 Comments
 
LVL 48

Expert Comment

by:AlexFM
ID: 9848367
0
 

Author Comment

by:sultan666
ID: 9848413
yes but how would this work?

i need a program that receives a string from the client and then sends the ACK string.
0
 
LVL 4

Expert Comment

by:skypalae
ID: 9848425
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
Simplifying Server Workload Migrations

This use case outlines the migration challenges that organizations face and how the Acronis AnyData Engine supports physical-to-physical (P2P), physical-to-virtual (P2V), virtual to physical (V2P), and cross-virtual (V2V) migration scenarios to address these challenges.

 
LVL 4

Expert Comment

by:skypalae
ID: 9848447
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
 

Author Comment

by:sultan666
ID: 9848464
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
 

Author Comment

by:sultan666
ID: 9848493
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
 
LVL 4

Expert Comment

by:skypalae
ID: 9848515
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
 

Author Comment

by:sultan666
ID: 9848681
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
 

Author Comment

by:sultan666
ID: 9848692
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
 
LVL 4

Accepted Solution

by:
skypalae earned 335 total points
ID: 9848749
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
 

Author Comment

by:sultan666
ID: 9848798
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
 

Author Comment

by:sultan666
ID: 9848866
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
 

Author Comment

by:sultan666
ID: 9848907
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
 
LVL 4

Expert Comment

by:skypalae
ID: 9849189
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
 
LVL 4

Expert Comment

by:skypalae
ID: 9849202
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
 

Author Comment

by:sultan666
ID: 9849374
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
 
LVL 4

Expert Comment

by:skypalae
ID: 9849445
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
 

Author Comment

by:sultan666
ID: 9849455
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
 
LVL 4

Expert Comment

by:skypalae
ID: 9849564
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
 

Author Comment

by:sultan666
ID: 9855803
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
 
LVL 4

Expert Comment

by:skypalae
ID: 9856040
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
 

Author Comment

by:sultan666
ID: 9856048
thank you
0

Featured Post

Comprehensive Backup Solutions for Microsoft

Acronis protects the complete Microsoft technology stack: Windows Server, Windows PC, laptop and Surface data; Microsoft business applications; Microsoft Hyper-V; Azure VMs; Microsoft Windows Server 2016; Microsoft Exchange 2016 and SQL Server 2016.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A list of useful business intelligence software.
Let’s list some of the technologies that enable smooth teleworking. 
The viewer will learn how to successfully create a multiboot device using the SARDU utility on Windows 7. Start the SARDU utility: Change the image directory to wherever you store your ISOs, this will prevent you from having 2 copies of an ISO wit…
The viewer will learn how to successfully download and install the SARDU utility on Windows 7, without downloading adware.

823 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question