CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 11 of 11
  1. #1
    Join Date
    Apr 2011
    Posts
    16

    Socket Send and OnReceive

    So im trying to connect to tor control port 9051.
    Sending anything with Send() function results in 0 response. Using PuTTy theres no such problem i mean im connecting to 127.0.0.1:9051 and lets say i send "bonjour" i will get following error: "514 Authentication required." and thats ok.

    Now thats my code:
    class CSockety : public CAsyncSocket
    {
    public:
    void OnReceive(int nError){AfxMessageBox(_T("received message"));}
    void OnSend(int nError){AfxMessageBox(_T("sent message"));}
    };

    CSockety socket_tor;
    socket_tor.Create();
    socket_tor.Connect(_T("127.0.0.1"),9051);
    socket_tor.Send("bonjour",strlen("bonjour"));



    Is there anything wrong ;/ ? OnReceive MessageBox doesnt appear when i call last line from my MFC Dialog based application -> button

    OnSend works properly, whats wrong with receiving ;/ ?

  2. #2
    Join Date
    Nov 2002
    Location
    California
    Posts
    4,556

    Re: Socket Send and OnReceive

    Code:
    CSockety socket_tor;
    socket_tor.Create();
    socket_tor.Connect(_T("127.0.0.1"),9051);
    socket_tor.Send("bonjour",strlen("bonjour"));
    Perhaps this code defines a local (stack) variable for the CSockety object that goes out of scope (and is destroyed) after the call to Send(). Show more code, so that we can confirm that the CSockety object persists beyond the call to Send(). One common approach is to make the CSockety object a member of a class.

    OnReceive MessageBox doesnt appear when i call last line from my MFC Dialog based application
    Never never use MessageBox to debug CAsyncSocket. CAsyncSocket relies for its functionality on the message queue, and MessageBox fundamentally alters the way the message queue is serviced.

    Use TRACE or equivalent instead.

    Mike

    PS: Use [ code ][ /code ] tags when posting code

  3. #3
    Join Date
    Apr 2011
    Posts
    16

    Re: Socket Send and OnReceive

    So im calling AfxSocketInit(); in my InitInstance()
    Code:
    void CtestDlg::TorManage(void)
    	{
    	socket_tor.Create();
    	socket_tor.Connect(_T("127.0.0.1"),9051);
    	send(socket_tor,"authenticate\0",strlen("authenticate\0"),0);
    
    	}
    void CtestDlg::OnBnClickedButtonTor()
    	{
    	TorManage();
    	}
    socket_tor is actually declared in CtestDlg class as:
    Code:
    CSockety socket_tor;
    so its not disapearing after calling the function.

    Connection is made because OnConnect message handler gives me the positive, yes again -> MessageBox

    Why does "OnSend MessageBox" work and when im expecting the same with OnReceive it will simply debug?

    Im want it to be the client only so i think that server implementation isnt needed here?(listen etc) Correct?

    EDIT1:
    Code:
    errorss =socket_tor.Connect(_T("127.0.0.1"),9051)
    		errorss = GetLastError();
    ;
    after calling first line errorss equals 0
    after 2nd line errorss remains 0. oO whats wrong?
    edit2:
    made few breakpoints changes and finally GetLastError returns 10035
    What are possible solutions?
    Last edited by qwqwqw12; May 3rd, 2011 at 07:18 AM.

  4. #4
    Join Date
    Nov 2002
    Location
    California
    Posts
    4,556

    Re: Socket Send and OnReceive

    Again: DO NOT USE MESSAGEBOX TO DEBUG CODE BASED ON CASYNCSOCKET.

    Just don't do it. If you understood CAsyncSocket, you would understand why. Since you don't understand CAsyncSocket, you just need to trust us. Use TRACE or write to a log file or something else, but do not use MessageBox.
    made few breakpoints changes and finally GetLastError returns 10035
    10035 is WSAEWOULDBLOCk, and it's completely expected. In fact, it's one of the most common return codes for non-blocking sockets (CAsyncSocket is both asynchronous and non-blocking).

    The basic principle in coding with CAsyncSocket is that the program is event driven, not sequential. The code you showed us is purely sequential, and must be re-written so that it is event-driven. To do so: The CAsyncSocket framework will tell you when events occur, and you must react appropriately, which usually means to do only one thing and then wait for another event. For example, call Connect() and then do nothing else until the connect-finished event arrives (it arrives in the form of a call to your OnConnect function). The only thing to do in OnConnect is to confirm that connection was successful, and if not, to take appropriate action (shutdown etc). Later on, another event will arrive, in OnSend. OnSend is called automatically after a successful call to Connect. Inside OnSend, call Send() to send your data and that's it. Later on, a read event will occur, and the framework will tell you by calling your OnReceive function. Inside OnReceive, call Receive to receive the data.

    The above description omits considerable amounts of error checking, which you also must do, but it describes the basic idea. Treat your CAsyncSocket-derived class like a finite state machine: keep track of where you are in the communication process, and determine what to do next when a new socket event arrives.

    Study the code here: "CHATTER: Demonstrates a Windows Sockets Client Application" at http://msdn.microsoft.com/en-us/libr...(v=vs.60).aspx
    ... and here: "Winsock Programmer’s FAQ
    Basic Winsock Examples: CAsyncSocket-based Client " at http://tangentsoft.net/wskfaq/exampl...ent/index.html

    Mike

  5. #5
    Join Date
    Apr 2011
    Posts
    16

    Re: Socket Send and OnReceive

    Im not sure i have understood ya correctly - "Event-driven" u mean one action at a time?

    Current code looks like this:
    Code:
    void CtestDlg::TorManage(void)
            {
            errorss =socket_tor.Create(2555,SOCK_STREAM,FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE);        
     
     
            errorss = socket_tor.Connect(_T("localhost"),9051);
                    errorss = GetLastError();
     
            }
    void CtestDlg::OnBnClickedButtonTor()
            {
            TorManage();
            }
     
    void CtestDlg::OnBnClickedButton1()
            {
             errorss =socket_tor.SendTo("authenticate \"h\"",strlen("authenticate \"h\""),2555,_T("127.0.0.1"),MSG_OOB);
     
            }
     
    void CtestDlg::OnBnClickedButton2()
            {
            //AfxMessageBox((LPCTSTR) (errorss));
            socket_tor.ShutDown(2);
            socket_tor.Close();
            }
    Class:
    Code:
    class CSockety : public CAsyncSocket
    {
     
    public:
            //void SetParentDlg(CDialog *pDlg);
            virtual void OnAccept(int nErrorCode){};
            virtual void OnClose(int nErrorCode){};
            virtual void OnConnect(int nErrorCode){};
            virtual void OnOutOfBandData(int nErrorCode){};
            virtual void OnReceive(int nErrorCode){}; 
    	virtual void OnSend(int nErrorCode){this->SendTo("authenticate \"h\"",strlen("authenticate \"h\""),MSG_OOB);}; 
    };
    Returned values:
    Code:
    errorss =socket_tor.Create(2555,SOCK_STREAM,FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE);       
    //errors=1 after calling
    errorss = socket_tor.Connect(_T("localhost"),9051); 
    //errors = 10035- correctly, then it calls OnConnect i OnSend, so it means that my connection was estabilished ( on port 9051, localhost)?
    errorss =socket_tor.SendTo("getconf maxci",strlen("getconf maxci"),2555,_T("127.0.0.1"),MSG_OOB); 
    // errors = 13 - correctly, 13 bits were sent. BUT: OnSend, wasnt called this time same happens if i put Send instead of SendTo here.
    OnClose isnt called when im closing connection is it normal?


    CAsyncSocket::SetSockOpt does it have something to do with my problem? Control Protocol seems to be secured so any non-authenticate msg kills my socket connection with the server.

    Screens from Debugging:
    http://snpr.cm/0baJL4.jpg
    http://snpr.cm/E2cTG0.jpg
    http://snpr.cm/jkSZ02.jpg
    http://snpr.cm/00w3yt.jpg
    http://snpr.cm/MeKRAf.jpg

    --------------------------------------------------
    Everything works now the problem was in incomplete msg It required \r\n at the end Thanks and good luck
    Last edited by qwqwqw12; May 3rd, 2011 at 02:21 PM.

  6. #6
    Join Date
    Apr 2011
    Posts
    16

    Re: Socket Send and OnReceive

    How can i gain access to objects created in my dialog class(CtestDlg) from CSockety?

    I want to edit "Edit control" box when packet arrives(OnReceive) but its saying that Cedit's object is undefined? Any idea?

    Tried to do something like this:
    Code:
    void CSockety::OnReceive(int nErrorCode)
    	{
    CtestDlg obj;
    SomeEditFunction(obj.TextToEdit);
    }
    but the hwnd in obj equals 0x00000000 so it doesnt change anything ;/
    TextToEdit is defined like this: CEdit TextToEdit and its a control variable of Edit Control.

    Edit1:
    Declared in CSockety class:
    Code:
    	CtestDlg *pjointer;
    Then:
    Code:
    void CSockety::OnReceive(int nErrorCode)
    	{
    	pjointer->Attach(AfxGetMainWnd()->m_hWndOwner);
    
    	SomeEditFunction(pjointer->TextWLog,_T("NewText"));
    	}
    SomeEditFunction(pjointer->TextWLog,_T("NewText"));
    // here my applications breaks with following error: http://snpr.cm/2RbxqU.jpg

    Edit2:
    I defined pjointer in global scope just before void CtestDlg::TorManage(void):
    Code:
    CtestDlg *pjointer;
    then added this line to void CtestDlg::TorManage(void):
    Code:
    void CtestDlg::TorManage(void)
    	{
    	errorss = socket_tor.Create(2555,SOCK_STREAM,FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE);	
    	errorss = socket_tor.Connect(_T("localhost"),9051);
    	::pjointer = this;
    	}
    and it surprisingly works oO. Im thinking about other "clean" solutions because once upon a time i read: "if u have to define globals something went wrong when you have been planning it". Any tips ;p?
    Last edited by qwqwqw12; May 4th, 2011 at 08:29 AM.

  7. #7
    Join Date
    Nov 2002
    Location
    California
    Posts
    4,556

    Re: Socket Send and OnReceive

    Quote Originally Posted by qwqwqw12 View Post
    ... Any tips ;p?
    Two quick thoughts (since you are correct that global variables generally indicate a bad achitecture).

    First, in CSockety, declare a member variable of type "CtestDlg*" (let's call it "pjointer", sort of along the lines of your Edit1 approach). Set this variable on the constructor of CSockety, which should be re-defined as follows:
    Code:
    // in the .h file, you probably will need to #include testDlg.h
    CSockety::Csockety(CtestDlg *p):pjointer( p ){};
    Now your CSockety class can access member variables and functions in the CtestDlg class.

    Second, use SendMessage to send a WM_SETTEXT message to the HWND of the edit control. Or SendMessage to send a customized message that has special meaning to you. This approach might be more OO, since even if the message is ignored or the HWND is invalid, it doesn'rt crash your program.

    Mike

  8. #8
    Join Date
    Apr 2011
    Posts
    16

    Re: Socket Send and OnReceive

    Itsss so hilarious ;d Out of the blue my IDD_TEST_DIALOG became undefined oO, HERE:
    Code:
    enum { IDD = IDD_TEST_DIALOG };
    So i found this solution to include resource.h to my dialog .h file. Why did it happen? There were also like mm dozen different errors:
    No default CSockety constructor, undefined CtestDlg class in Csockety .h file so i added this line before my class:
    class CtestDlg;
    cause i saw it somewhere and thought that its worth the shoot ;D

    Now the last error is above my knowledge ;D
    Error 1 error C2079: 'CtestDlg::socket_tor' uses undefined class 'CSockety' \testdlg.h
    http://snpr.cm/4neac8.jpg
    Line 50(different statement): http://snpr.cm/1wmyQM.jpg
    And now to make things clear: i "declared" this lines before CtestDlg class:
    Code:
    #include "CSockety.h"
    #include "resource.h"
    class CSockety;
    Deleting last line results in following errors: http://snpr.cm/aKB3rB.jpg
    It might be connected with CSockety constructors? MY class looks as follows:
    Code:
    #pragma once
    #include "afxsock.h"
    class CtestDlg;
    class CSockety :public CAsyncSocket
    {
    public:
    	CtestDlg*pjointer;
    	CSockety(){};
    	CSockety(CtestDlg *p):pjointer( p ){};
    	~CSockety(void);
    	virtual void OnAccept(int nErrorCode){};
    	virtual void OnClose(int nErrorCode){};
    	virtual void OnConnect(int nErrorCode){};
    	virtual void OnOutOfBandData(int nErrorCode){};
    	virtual void OnReceive(int nErrorCode); 
    	virtual void OnSend(int nErrorCode){this->Send("auth \"h\"\r\n",strlen("auth \"h\"\r\n"));}
    };
    1.Im also not sure about constructor i made, what did ya mean by "Set this variable on the constructor of CSockety". It doesnt point to orginal CtestDlg class right now hmm?
    And another things:
    2. What are Google keywords for this magic(constructor) u made in CSockety class. So i could read about it
    3. My "Edit Control" box is some kind of "Log Window" everything that happens in my application goes there. So the question is will SendMessage add new lines to the end of my box and scroll it down to the last line when theres more entries? Im actually using this function to do it for me and it works:
    Code:
    void AppendTextToEditCtrl(HWND hWndEdit, LPCTSTR pszText)
    {
       int nLength = Edit_GetTextLength(hWndEdit); 
       Edit_SetSel(hWndEdit, nLength, nLength);
       Edit_ReplaceSel(hWndEdit, pszText);
    }
    Edit:
    Ok i have deleted some includes(testdlg.h from CSockety.h file) and now it seems to work except my new constructor Also Points 2 and 3 r still actual ;p
    Tried to make static pjointer, but it didnt work -> http://snpr.cm/H1WGLm.jpg:
    static CtestDlg*pjointer;
    So i could put "this" from CtestDlg in it. What might help?
    Last edited by qwqwqw12; May 5th, 2011 at 03:23 AM.

  9. #9
    Join Date
    May 2011
    Location
    Berlin / Germany
    Posts
    1

    Re: Socket Send and OnReceive

    Thanks for your help

  10. #10
    Join Date
    Nov 2002
    Location
    California
    Posts
    4,556

    Re: Socket Send and OnReceive

    OK, the new constructor for CSockety won't work. The reason is that it replaces the default constructor, and since you have CSockety as a member variable in CtestDlg, CtestDlg will need the default constructor (ie, the no-argument constructor).

    Go back to the no-argument constructor.

    Maintain the member variable in CSockety for a pointer to CtestDlg. IOW, in the .h file for CSockety, there should be something like this:
    Code:
    class CSockety :public CAsyncSocket
    {
    public:
    	CtestDlg*pjointer; // etc
    }
    Also, maintain the member variable for a CSockety object inside your CtestDlg class. I think this is currently called socket_tor

    Then, in the constructor of CtestDlg, intialize the pointer:
    Code:
    CtestDlg::CtestDlg()
    {
      socket_tor.pjointer = this;
    }
    Start a new thread if you continue to enconter issues. The current thread has moved far away from the subject matter of your initial inquiry.

    Mike

  11. #11
    Join Date
    Apr 2011
    Posts
    16

    Re: Socket Send and OnReceive

    Hmm It worked Im gonna try some dll injection now, and to finish things up here mmm... Where can i find more info about the first method in CSockety class? It's sort of friendship declaration yet different.
    Last edited by qwqwqw12; May 6th, 2011 at 02:01 AM.

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