Solved

listening to a port on the local host

Posted on 2003-11-30
22
556 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
Comment Utility
0
 

Author Comment

by:sultan666
Comment Utility
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
Comment Utility
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
 
LVL 4

Expert Comment

by:skypalae
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

 

Author Comment

by:sultan666
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
thank you
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

Suggested Solutions

I use more than 1 computer in my office for various reasons. Multiple keyboards and mice take up more than just extra space, they make working a little more complicated. Using one mouse and keyboard for all of my computers makes life easier. This co…
In our personal lives, we have well-designed consumer apps to delight us and make even the most complex transactions simple. Many enterprise applications, however, are a bit behind the times. For an enterprise app to be successful in today's tech wo…
Video by: Tony
This video teaches viewers how to export a project from Adobe Premiere Pro and the various file types involved.
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

763 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

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now