Visualizzazione dei risultati da 1 a 10 su 10
  1. #1

    [C++] modificare funzione

    Salve,

    avrei bisogno di modificare la seguente funzione in modo che non ritorni std::string ma char*

    codice:
    std::string Socket::ReceiveBytes() {
      std::string ret;
      char buf[1024];
     
      while (1) {
        u_long arg = 0;
        if (ioctlsocket(s_, FIONREAD, &arg) != 0)
          break;
    
        if (arg == 0)
          break;
    
        if (arg > 1024) arg = 1024;
    
        int rv = recv (s_, buf, arg, 0);
        if (rv <= 0) break;
    
        std::string t;
    
        t.assign (buf, rv);
        ret += t;
      }
     
      return ret;
    }
    vorrei che il prototipo di funzione fosse così:

    bool Socket::ReceiveBytes(char * buffer, const int buffeSize)
    così posso scegliere quanto leggere...

    grazie
    Alla batteria dai retta ballA

  2. #2
    diciampo che ho cambiato il prototipo così:

    int bytesreceived = Socket::ReceiveBytes(char * buf, int bufsize);
    e questo è il codice che mi è venuto in mente fin'ora (non testato)

    Codice PHP:
    #include <algorithm>

    int Socket::ReceiveBytes(char bufferint buffersize)
    {
        if(
    buffersize 32768)
            
    buffersize 32768;

        
    char temp[32768];
        
    int byrv 0;

        while (
    1)
        {
            
    u_long arg 0;

            if (
    ioctlsocket(s_FIONREAD, &arg) != 0)
                return -
    1;

            if (
    arg == 0)
                return 
    byrv;

            if (
    arg buffersize)
                
    arg buffersize;

            
    int rv recv (s_temparg0);

            if (
    rv <= 0)
                return -
    1;

            
    std::copy(temptemp rvbuffer);
            
    byrv += rv;
        }

    Alla batteria dai retta ballA

  3. #3
    forse questa ha più senso:

    Codice PHP:
    #include <algorithm>

    int Socket::ReceiveBytes(char bufferint buffersize)
    {
        if(
    buffersize 32768)
            
    buffersize 32768;

        
    char temp[32768];
        
    int byrv 0;

        
    u_long arg 0;

        if (
    ioctlsocket(s_FIONREAD, &arg) != 0)
            return -
    1;

        if (
    arg == 0)
            return 
    byrv;

        if (
    arg buffersize)
            
    arg buffersize;

        
    int rv recv (s_temparg0);

        if (
    rv <= 0)
        {
            return -
    1;
        } else {
            
    std::copy(temptemp rvbuffer);
        }

    dove in:

    codice:
    ioctlsocket(s_, FIONREAD, &arg);
    mi ritorna in arg quanto ho dal leggere dal socket...
    Alla batteria dai retta ballA

  4. #4
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Scusa, ma non è meglio così?

    Codice PHP:

    int Socket
    ::ReceiveBytes(char bufferint buffersize)
    {
        
    u_long arg 0;

        if (
    ioctlsocket(s_FIONREAD, &arg) != 0)
            return -
    1;

        if (
    arg == 0)
            return -
    1;

        if (
    arg buffersize)
            
    arg buffersize;

        return 
    recv (s_bufferarg0);
    }

    ...

    int bytesReceived =  Socket::ReceiveBytes(buffdimensione); 
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  5. #5
    decisamente
    Alla batteria dai retta ballA

  6. #6
    solo una cosa...mi sa che devo usare il casting:

    Codice PHP:
    int Socket::ReceiveBytes(char buffer, const int buffersize)
    {
        
    u_long arg 0;

        if (
    ioctlsocket(s_FIONREAD, &arg) != 0)
            return -
    1;

        if (
    arg == 0)
            return -
    1;

        if (
    arg > (u_long)buffersize)
            
    arg = (u_long)buffersize;

        return 
    recv (s_buffer, (int)arg0);

    altrimenti mi da unsigned mismatch in if (arg > (u_long)buffersize) e allora ho approfitatto per fare casting anche nell'assegnazione e in recv
    Alla batteria dai retta ballA

  7. #7
    cmq c'è un comportamento strano dela funzione...se gli passo un buffer minore rispetto al documento che mi arriva me lo legge più volte:

    codice:
    	const int buffsz = 1024;
    	char buffer[buffsz] = {0};
    	while(1)
    	{
    		int k = s.ReceiveBytes(buffer, buffsz);
    		if(k<=0)
    			break;
    
    		cout << buffer;
    	}
    mah...
    Alla batteria dai retta ballA

  8. #8
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,465
    Se visualizzi una stringa terminata da zero contenuta nel buffer, ti devi accertare che lo zero finale venga trasmesso alla fine della stringa, altrimenti potresti visualizzare parti di stringa "precedenti" ...
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  9. #9
    oddio, non credo di avercapito...in pratica non se se perchè chiamo recv più volte...ma io devo leggere la response a chunks e non in un colpo solo...altrimenti se mi rispondono con Mb di dati binari che faccio?

    codice:
    int Socket::ReceiveBytes(char * buffer, const int buffersize)
    {
    	u_long arg = 0;
    	if (ioctlsocket(s_, FIONREAD, &arg) != 0)
    		return -1;
    
    	if (arg == 0)
    		return -1;
    
    	if (arg > (u_long)buffersize)
    		arg = buffersize;
    
    	return recv (s_, buffer, arg, 0);
    }
    nella funzione recv legge i dati disponibile nel buffer...l'informazione l'a ottiene tramite ioctlsocket. se la response ad esempio pesa 1500...se mando un buffer di 2048 va bene (letta in un colpo) se gli mando due buffer da 1024 (quindi due chiamate alla funzione ReceiveBytes) mi ritorna più di una volta lo stesso documento con in mezzo qualche carattere non-printable (sto provando aleggere file ascii per adesso)
    Alla batteria dai retta ballA

  10. #10
    forse ho capito, la recv legge una certa quantità di dati nel buffer interno del winsock. La dimensione minima del buffer si ottine tramite ioctlsocket(FIONREAD).

    Ora io devo leggere almeno quella quantità e non di meno, altrimenti succede quello che succede. Forse mi ero fatto distrarre da queste piccole quantità di dati. Infatti provando a scaricare un file di vari mega la winsock lo legge a chunks non maggiori di 8192! Logico che se io gli passo un buffer di 1024 si incasina tutto.

    Al contrario io ora gli passero sempre un buffer grande ad esmepio:

    Codice PHP:
        const int buffsz 32768;
        
    char buffer[buffsz] = {0};
        while(
    s.ReceiveBytes(bufferbuffsz)>0)
        {
            
    cout << buffer;
            
    system("pause");
        } 
    o anche 65535...tanto non leggerà mai così tanti dati un un ciclo solo...la funziona mi ritornerà quanti dati effetivamente sono stati letti e mi regolerò di conseguenza..tanto difficilmente la winsock internamente avrà un buffer maggiore di 32768 o magari il doppio...eppure mi ricordo che su unix era più facile
    Alla batteria dai retta ballA

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.