Thread: char problem

  1. #1
    Registered User
    Join Date
    Dec 2004
    Posts
    103

    char problem

    i got this code..
    Code:
    void CChateXDlg::OnReceive(int nErrorCode)
    {
    	if(nErrorCode==0)
    	{
    		char Data[1000];
    		wsClient.Receive(Data,1000,0);
    		m_re1+=Data;
    		UpdateData(FALSE);
    	}
    }
    the Receive function requires wsClient.Receive(void *lpbuf,strlen of the data, and nflags)
    problem is that i dont want to declare 1000 chars char i want it to take only how much it needs, any ideas how to do that ?

    thanks

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > any ideas how to do that ?
    It's a waste of time IMO

    > m_re1+=Data;
    As soon as you do this, Data is about to go out of scope, so whatever space it used is about to be reclaimed anyway.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Dec 2004
    Posts
    103
    yea i know but what about if there are more than 1000 chars comming..?

  4. #4
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    Then you need to call Receive() more than once.

  5. #5
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Calling Recieve() with the MSG_PEEK flag and catching the return should tell you the amount of data waiting (without reading/removing the data).

    If you are worried about the size of the data exceeding the recv buffer then use getsockopt(.....SO_RCVBUF) and allocate the buffer to match recieve buffer size.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  6. #6
    Registered User
    Join Date
    Dec 2004
    Posts
    103
    Quote Originally Posted by novacain
    Calling Recieve() with the MSG_PEEK flag and catching the return should tell you the amount of data waiting (without reading/removing the data).
    exactly what i need but one last thing how do i use it to declare the ammount of chars needed, oh and how do i use the function to get that ammount.. lol cant get it work, a small example would be really perfect :P

  7. #7
    return 0;
    Join Date
    Jan 2005
    Location
    Netherlands
    Posts
    89
    I don't know C++, but here's what it should look like:

    Code:
    size = 100;
    buffer = [create array of 'size' bytes];
    
    while((length = wsClient.Receive(buffer,size,MSG_PEEK)) == size) {
      size += 100;
      buffer = [make array 100 bytes bigger];
    }
    
    wsClient.Receive(buffer,size,0);
    m_re1 += buffer;
    
    [release buffer];
    The concept is that Receive returns the number of bytes received. While this amount is equal to our buffer size, there might be more waiting. So we increase our buffer size and try again. The MSG_PEEK option makes sure that the received data isn't removed from the queu. When Receive returns a value not equal to our buffer size, it means we've read all the data in our buffer, so we can call Receive without the MSG_PEEK flag to remove the data from the queu.

    Btw you should do some extra error checking. Check wether Receive returns 0 or less (which means the socket is closed or there was an error) and check wether the buffer isn't NULL

  8. #8
    Registered User
    Join Date
    Dec 2004
    Posts
    103
    hmm but wsClient.Receive doesnt return anything i tried it and even if it did return the number of the chars received cant i declare something like
    int nr_chars;
    char Data[nr_chars];

  9. #9
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Sorry.......on closer examination PEEKing will not help that much.

    If you PEEK and get returned a SOCKET_ERROR. Then call GetLastError() and fins a WSAEMSGSIZE error. Then the buffer was too small. It will not tell you by how much. You would have to realloc the buffer and try again until the buffer was big enough. Then make a call again to remove the data.

    Look at setsockopt() (from Ws2_32.lib, Winsock2.h or MFC CAsyncSocket). This will allow you to set the size of the buffers used. Or getsockopt() to find the buffer size it is using

    //something like (in MFC)
    Code:
    wsClient.GetSockOpt(SO_RCVBUF , &iBufferSize, sizeof(int), SOL_SOCKET );
    
    char *pBuffer = new[iBufferSize+1];
    //error check
    //use
    
    //clean up
    delete [] pBuffer;
    pBuffer=NULL;
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  10. #10
    Registered User
    Join Date
    Dec 2004
    Posts
    103
    thx.. but this is quite the same problem this is what i hate about c++ why the hell do i have to give char variable there AND i gotta guess the len of it btw int has 32000 right ? and thats 32 kb what if the user sends more than that.. it is really the same problem.. oh and i found another problem a problem which i had in visual basic too and i thought that switching to c++ i wont find this problem there so anyway its about the rich edit control i use 2.0 but doesnt matter its the same bug on 1.0 too here is a screenie > the scrollbar is down and the text is up very nice bug.. this happens when i resize the height of the rich edit control is there any good way to fix this damn annoying bug?(except to scroll the whole text up then down that is not a very cool way :P) thanks

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    I really wish people would stick to solving one problem at a time.

    Until you're sure you can connect and receive all your data, and store it in sensible data structures with complete accuracy, then there isn't much point in attaching a glossy UI to it.

    Maybe the bug is in the receive code, and maybe the bug is in the UI code - you just can't tell.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  12. #12
    Registered User
    Join Date
    Dec 2004
    Posts
    103
    sorry.. about that getting size problem it just looks like there is no real good way to get the data size so you declare a 10 mb char where hell knows how much will be used from it maybe there is more who knows.. but what instead of the char thing it could require a cool cstring without the len thing.. wouldnt that be easier and better ? i still cant understand why they put that char thing, and btw..
    Quote Originally Posted by Salem
    Until you're sure you can connect and receive all your data...
    thats the point i dont receive all the data because i dont even know how much memory to declare a char to get it
    Last edited by eXistenZ; 02-14-2005 at 08:24 AM.

  13. #13
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Like everything else, the data is fetched in blocks, and those blocks are chained together in some way in your code.

    How do you think things like FTP and browsers fetch variable amounts of data from just a few bytes to many megabytes.

    Browsers in particular fetch some data, display a bit of it, fetch some more data, display some more data etc etc.

    IP is naturally based on finite block sizes, so how about starting there.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  14. #14
    Registered User
    Join Date
    Dec 2004
    Posts
    103
    im not sure if this is the same as in visual basic but isn't there only 1 variable that has all the data so if the server sends to the client some data("1" for example) and then sends again some other data("2" for example) and if the client is laggy or if the server is laggy the client might receive the data mixed up something like this "12" oh yea i know theres another way you could just wait until the first data is 100% sent and then you send the second data well that will cause HUGE lagg for a chat program
    k sorry all of this talk wont do anything is there really no other way to get the data size..? really i dont think: wsClient.GetSockOpt(SO_RCVBUF , &iBufferSize, sizeof(int), SOL_SOCKET );
    returns the data lenght into the iBufferSize, isnt it the buffer itself ?
    Last edited by eXistenZ; 02-14-2005 at 10:59 AM.

  15. #15
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Woah there eXistenZ!

    one thing at a time.


    >>the data is fetched in blocks,

    the block size being up to the sockets 'internal' recv buffer. More than this size will result in multiple recv msgs.

    So if you set you buffer > the sockets 'internal' recv buffer there will never be more data recv than buffer size.
    You may get less.
    The number of bytes read is returned (as an int) by Receive()

    >>Browsers in particular fetch some data, display a bit of it, fetch some more data, display some more data etc

    this is done by 'packets'.
    Some way to tell the end of piece of data (and so the start of the next).
    A packet can be a complex structure or a int (= size of msg).

    Something like..
    Code:
    recv size = Socket.Receive(,,)
    
    if (have data stored)
         add new data to end of stored data
         recv size += stored size
    
    used = 0; // reset counter
    msg size = recv size+1 // so second IF will fail until packet read
    
    while (recv size < used )
    
        If (recv size - used ) >= Packet size
             read Packet
             find msg size
             used  += packet size
             
        If (recv size - used ) >= msg size 
             read msg
             use msg (display)
             used  += msg size
        else 
            store data (until full amount recv'ed)
            remember details (ie msg size, stored size, packet or msg)
            used += stored size
    Last edited by novacain; 02-14-2005 at 11:10 AM.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need help understanding info in a header file
    By hicpics in forum C Programming
    Replies: 8
    Last Post: 12-02-2005, 12:36 PM
  2. char problem
    By ForlornOdium in forum C++ Programming
    Replies: 10
    Last Post: 10-29-2003, 02:39 PM
  3. simulate Grep command in Unix using C
    By laxmi in forum C Programming
    Replies: 6
    Last Post: 05-10-2002, 04:10 PM
  4. String Processing Problem
    By muffin in forum C Programming
    Replies: 0
    Last Post: 08-24-2001, 10:13 AM