Click here to Skip to main content
15,881,248 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hello,

I have configured my raspberry pi as a server and my Windows pc as a client.

The raspberry pi sends an image to the pc when connection is established.

on the PC side, i am using Visual studio. I have included the dependencies of openCV2

i used the following command: image = fopen_s(fn, "wb"); but it doesnt work.

I am receving the data from the pi,meaning that the image is being recevied. But i need a mode to display the same image on my windows pc.

the code below is the image function of my client side. I have simply called the above function when the connection (bind, listen, accept) is established in my main program

What I have tried:

#pragma once

#include <stdio.h>
#include <string.h>
#include <winsock2.h> 
#include <iostream>
#include <fstream>
#include <errno.h>
#include <iostream>
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <conio.h>
#include 
#include 

using namespace cv;
using namespace std;

int receive_image(int socket)
{ // Start function 
	int imgc = 0 ; 

	while(imgc < 2000)
	{
		int buffersize = 0, recv_size = 0,size = 0, read_size, write_size,  packet_index =1; //,stat;

		char imagearray[10240],verify = '1';
		FILE *image=0;
		int value = 0 ; 
		//Find the size of the image

		value = value + 1;  

		char wzRec[10240];
		int nLeft= 512, nLefts = 512;
		int iPos= 0, iPos2 = 0;
		int nData = 0;

		do
		{
			nData = recv( socket, &wzRec[iPos], nLeft, 0 );
			if( nData == SOCKET_ERROR ) 
			{
				cout << "Error receiving data" << endl;
				break;
			}
		}while( nLeft > 0);

		printf("size = %d" , size) ; 

		if(size>1000)
		{
			imgc = imgc + 1 ; 
			char buffer[] = "Got it";

			//Send our verification signal
				do
				{ 
					nData = send( socket, &buffer[iPos2], nLeft, 0 );
					if( nData == SOCKET_ERROR )
					{
						cout<< "Error sending data" << endl;
						break;
					}
					nLefts -= nData;
					iPos2 += nData;
				}while( nLefts > 0);
    

				printf("Reply sent\n");
				printf(" \n");

				//char fn[100] ; 

				//sprintf_s(fn,"a%d.jpg",imgc);
				////sprintf(fn,"a%d.jpg",imgc);

				//image = fopen_s(fn, "wb");
				////image = fopen(fn, "wb"); 
				 
				
				if( image == NULL)
				{
					printf("Error has occurred. Image file could not be opened\n");
					return -1; 
				}

				//Loop while we have not received the entire file yet

				int need_exit = 0;
				struct timeval timeout = {10,0};

				fd_set fds;
				int buffer_fd, buffer_out;

				while(recv_size < size)
				{
					//while(packet_index < 2){
					FD_ZERO(&fds);
					FD_SET(socket,&fds);

					buffer_fd = select(FD_SETSIZE,&fds,NULL,NULL,&timeout);
					if (buffer_fd < 0)
					printf("error: bad file descriptor set.\n");

					if (buffer_fd == 0)
						printf("error: buffer read timeout expired.\n");

					if (buffer_fd > 0)
					{
						do
						{
							read_size = recv(socket,imagearray, 10240,0);
							//read_size = read(socket,imagearray, 10240);
						}while(read_size <0);

					printf("Packet number received: %i\n",packet_index);
					printf("Packet size: %i\n",read_size);

					//Write the currently read data into our image file
					write_size = fwrite(imagearray,1,read_size, image);
					printf("Written image size: %i\n",write_size); 

					if(read_size !=write_size) 
					{
						printf("error in read write\n");
					}

					//Increment the total number of bytes read
					recv_size += read_size;
					packet_index++;
					printf("Total received image size: %i\n",recv_size);
					printf(" \n");
					printf(" \n");
					}
				}

				fclose(image);
				printf("Image successfully Received!\n");    
	
		}
	}
	return 1;
}

int main(int argc, char* argv[])
{
	// Initialize WinSock2.2 DLL
	// low word = major, highword = minor
	WSADATA wsaData = {0};
	WORD wVer = MAKEWORD(2,2);
	int nRet = WSAStartup( wVer, &wsaData );
	if( nRet == SOCKET_ERROR )
	{
		printf("Failed to init Winsock library");
		//cout << "Failed to init Winsock library" << endl;
		return -1;
	}
	cout << "Opening connection to server" << endl;
	WORD WSAEvent = 0;
	WORD WSAErr = 0;
	SOCKET hServer = {0};
	// open a socket
	//
	// for the server we do not want to specify a network address
	// we should always use INADDR_ANY to allow the protocal stack
	// to assign a local IP address
	hServer = socket( AF_INET, SOCK_STREAM, IPPROTO_IP );
	if( hServer == INVALID_SOCKET )
	{
		cout << "Invalid socket, failed to create socket" << endl;
		return -1;
	}
	// name a socket
	sockaddr_in saServer = {0};
	saServer.sin_family = PF_INET;
	saServer.sin_port = htons( 5001 );
	//saServer.sin_port = htons( 10000 );
	//saServer.sin_addr.s_addr = inet_addr( "127.0.0.2" );
	saServer.sin_addr.s_addr = inet_addr( "172.16.26.100" );

	// connect
	nRet = connect( hServer, (sockaddr*)&saServer, sizeof( sockaddr ) );
	if( nRet == SOCKET_ERROR ) 
	{
		cout << "Connection to server failed" << endl;
		closesocket( hServer );
		return -1;
	}
	cout << "Connected to server" << endl;
	cout << "Sending data to server" << endl;



	receive_image(hServer);

	cout << "Closing connection" << endl;

	// shutdown socket

	nRet = shutdown( hServer, SD_BOTH );
	if( nRet == SOCKET_ERROR ) 
	{
		// WSAGetLastError()
		cout << "Error trying to perform shutdown on socket" << endl;
		return -1;
	}
	
	// close server socket
	nRet = closesocket( hServer );
	hServer = 0;
	if( nRet == SOCKET_ERROR )
	{
		cout << "Error failed to close socket" << endl;
	}
	// Release WinSock DLL
	nRet = WSACleanup();
	if( nRet == SOCKET_ERROR )
	{
		cout << "Error cleaning up Winsock Library" << endl;
		return -1;
	}
	cout << "Data sent successfully" << endl;
	getchar();
	return 0;
}
Posted
Updated 29-Mar-16 3:50am
v2

1 solution

When fopen() fails (returns NULL) check the global variable errno to know why opening the file failed and optionally get the error message using strerror(). To have access to errno, include the header file errno.h:
C++
 #include <errno.h>
// ...
if( image == NULL)
{
    int err = errno;
    printf("Error %d has occurred: %s\n", err, strerror(err));
    return -1;
}

[EDIT]
Or using the safe functions:
C++
sprintf_s(fn, sizeof(fn), "a%d.jpg", imgc);
int err = fopen_s(&image, fn, "wb");
if (err)
{
    printf("Error %d has occurred: %s\n", err, strerror(err));
    return -1;
}
[/EDIT]

A probable error has code 13 (EACCES / "Permission denied") because you are specifying the file name without path so that the current working directory is used to which you might not have write access.
 
Share this answer
 
v3
Comments
violence666 29-Mar-16 10:17am    
If i uncomment fopen (or sprintf) i get the following

error C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
Jochen Arndt 29-Mar-16 10:26am    
Than do what is shown in the message:
Use sprintf_s and fopen_s instead or disable that error setting.

I have updated my answer with code for the safe functions.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900