Hilfe bei Bildübertragung per Netzwerk



  • Hi leute,
    ich habe die letzten tage versucht ein bild über einen Socket zu senden, doch leider funktioniert das zusammensetzen auf Client-Seite nicht;
    Hier ist das zu sendende Bild:
    http://img535.imageshack.us/img535/742/testxr.jpg
    und hier das, was auf Client-Seite rauskommt:
    http://img85.imageshack.us/img85/4955/recvx.jpg

    Ich bin mir sicher das der fehler auf client-seite ist, da das bild auf dem server richtig zerlegt wird.
    Es wird vor der Dateiübertragung ein header gesendet der mit "<" und ">" gekennzeichnet ist; in diesem stehen die relevanten informationen (größe,kanäle)

    Der Epmfangscode sieht folgendermaßen aus:

    IplImage *img;
    int temp_count = 0;
    bool data_transfer = false;
    
    void readHandler(string c, int readBytes) // !!!not thread-safe!!!
    {	
    	if(!data_transfer)
    	{
    		int header_start = c.find("<");
    		int header_end = c.find(">");
    		if(header_start==header_end) // normaler text
    		{
    			cout << c; 
    		}
    		if(header_start < header_end)
    		{
    
    			data_transfer = true;
    
    			int start = c.find("length=");
    			int len = c.find(";",start) - start - 7; // length of number
    			int tcp_out_count = atoi(c.substr(start + 7,len).c_str()); //size
    
    			start = c.find("width=");
    			len = c.find(";",start) - start - 6;
    			int width = atoi(c.substr(start + 6,len).c_str()); //width
    
    			start = c.find("height=");
    			len = c.find(";",start) - start - 7;
    			int height = atoi(c.substr(start + 7,len).c_str()); //height
    
    			start = c.find("depth=");
    			len = c.find(";",start) - start - 6;
    			int depth = atoi(c.substr(start + 6,len).c_str()); //depth
    
    			start = c.find("channels=");
    			len = c.find(";",start) - start - 9;
    			int channels = atoi(c.substr(start + 9,len).c_str()); //channels
    
    			img = cvCreateImage(cvSize(width,height), IPL_DEPTH_8U, channels); //TODO: coversion from int depth to valid input
    
    		}
    	}
    	else
    	{
    		for (int j=0; j<readBytes && j<1024; j++)
    		{
    			img->imageData[temp_count*1024+j] = c[j];
    		}
    		if(temp_count >= img->imageSize/1024-1)
    		{
    			cout << "<finished>" << endl;
    			cout.flush();
    			cvSaveImage("recv.jpg",img);
    
    			temp_count = 0;
    			data_transfer = false;
    		}
    		temp_count++;
    	}
    }
    

    ich hoffe es hat jemand zeit sich das anzusehen;

    LG



  • Da die erste Unregelmäßigkeit rechts unten bei einem dunklen Pixel anfängt, gehe ich davon aus, dass es etwas mit der Nullterminierung von string zu tun hat. Du solltest stattdessen vector<unsigned char> verwenden.
    Und wenn du so ein Monstrum als Parameter übergibst, solltest du das unbedingt per Referenz machen.



  • Tatsächlich du hattest Recht... es lag wirklich an der null-terminierung von strings (bzw daran das im Bild auch der Wert 0 vorkommt);

    Jetzt wird das Bild beim ersten Mal richtig übertragen, beim 2ten mal ist es wieder falsch (http://img534.imageshack.us/img534/8940/recv.jpg) und beim 3ten versuch bekomme ich folgende Antwort:

    Program received signal SIGSEGV, Segmentation fault.
    [Switching to Thread 0xb7fd3b70 (LWP 16935)]
    0x0804b512 in readHandler (
        c=0xbfffef18 "\"\n\024-\026\024*\027\020:)&?12)\037%\"\032$\036\030#\t\005\021#\037+%\037*\032\022\031\037\024\027\063! $\020\v\027", readBytes=1024)
        at client.cpp:226
    226				img->imageData[temp_count*1024+j] = c[j];
    

    Das sieht so aus als obe c nicht die 1024 Bytes sind die es sein sollten, aber ich weiß nicht warum...

    Hier nochmal der angepasste code (is nicht schön, aber es muss vorerst tun):

    IplImage *img;
    int temp_count = 0;
    bool data_transfer = false;
    
    void readHandler(char *c, int readBytes) // !!!not thread-safe!!!
    {	
    	//cout << c->length() << endl;
    	if(!data_transfer)
    	{
    		string s(c);
    		int header_start = s.find("<");
    		int header_end = s.find(">");
    		if(header_start==header_end)
    		{
    			cout << s;
    		}
    		if(header_start < header_end)
    		{
    
    			data_transfer = true;
    
    			int start =  s.find("length=",start);
    			int len = s.find(";",start) - start - 7; // length of number
    			int tcp_out_count = atoi(s.substr(start + 7,len).c_str()); //size
    
    			start = s.find("width=");
    			len = s.find(";",start) - start - 6;
    			int width = atoi(s.substr(start + 6,len).c_str()); //width
    
    			start = s.find("height=");
    			len = s.find(";",start) - start - 7;
    			int height = atoi(s.substr(start + 7,len).c_str()); //height
    
    			start = s.find("depth=");
    			len = s.find(";",start) - start - 6;
    			int depth = atoi(s.substr(start + 6,len).c_str()); //depth
    
    			start = s.find("channels=");
    			len = s.find(";",start) - start - 9;
    			int channels = atoi(s.substr(start + 9,len).c_str()); //channels
    
    			img = cvCreateImage(cvSize(width,height), IPL_DEPTH_8U, channels); //TODO: coversion from int depth to valid input
    
    		}
    	}
    	else
    	{
    		for (int j=0; j<readBytes && j<1024; j++)
    		{
    			img->imageData[temp_count*1024+j] = c[j];
    		}
    		if(temp_count >= img->imageSize/1024-1)
    		{
    			cout << "<finished>" << endl;
    			cout.flush();
    			cvSaveImage("recv.jpg",img);
    
    			//tcp_out_count = -1;
    			temp_count = 0;
    			data_transfer = false;
    		}
    		temp_count++;
    	}
    }
    

    und hier die empfangenden funktionen:

    void read_start(void) 
            { // Start an asynchronous read and call read_complete when it completes or fails 
    
                    socket_.async_read_some(boost::asio::buffer(buffer, 1024), 
                            boost::bind(&tcp_client::read_complete, 
                                    this, 
                                    boost::asio::placeholders::error, 
                                    boost::asio::placeholders::bytes_transferred)); 
            } 
    
            void read_complete(const boost::system::error_code& error, size_t bytes_transferred) 
            { // the asynchronous read operation has now completed or failed and returned an error 
                    if (!error) 
                    { // read completed, so process the data 
    
                    	//buffer[bytes_transferred] = '\0';
    
                    	//cout << buffer;
    
                    	myPtr(&buffer[0], bytes_transferred);
    
                            //cout.write(buffer, bytes_transferred); // echo to standard output 
                            //cout << "\n"; 
                            read_start(); // start waiting for another asynchronous read again 
                    } 
                    else 
                            do_close(); 
            }
    

    wobei buffer so definiert ist:

    char buffer[1024];
    

    LG


Anmelden zum Antworten