update:
Since my initial question was very specific, i would like to start of with asking how do i inititate a simple bidirectional communication using tcp/ip?
Hello,
I want to receive H.264 video stream from a TCP/IP socket (without use of RTSP or other internet streaming protocols) from a Raspberry pi camera to my windows OS.
Previously the data was stored in a buffer and then sent to the windows side. but the cache memory fills up and i cant get continous video streaming.
Also, it would be really helpful if i could get a bidirectional connection via TCP/IP. On PC side,i want to use an easy-to-use C++ library for communication with the Raspberry Pi. The communication would consist of sending commands like “Set Camera Resolution” or “Start/Stop Grabbing” to the Raspberry Pi as well as of receiving and decoding of grabbed images. The library should be portable at least for MS Windows and Linux.
I am currently designing the code using c++ in visual studio 2012. The reason being that to make the program portable in other os, i would need minimum dependencies (c# uses .net libraries which make it tedious to configure on a linux os)>
Thank you in advance
What I have tried:
i tried the following code (from this site) using winsock2.h and WS2_32.lib. the code is unidirection between 2 windows computers. the IP adressing is static for the client.
------------------server side----------------------------------------------
#include <winsock2.h>
#include <iostream>
#include <process.h>
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
using namespace std;
int _tmain(int argc, _TCHAR* 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 )
{
// WSAGetLastError()
cout << "Failed to init Winsock library" << endl;
return -1;
}
cout << "Starting server" << endl;
// name a socket
WORD WSAEvent = 0;
WORD WSAErr = 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
SOCKET hSock = {0};
hSock = socket( AF_INET, SOCK_STREAM, IPPROTO_IP );
if( hSock == INVALID_SOCKET )
{
cout << "Invalid socket, failed to create socket" << endl;
return -1;
}
// name socket
sockaddr_in saListen = {0};
saListen.sin_family = PF_INET;
saListen.sin_port = htons( 10000 );
saListen.sin_addr.s_addr = htonl( INADDR_ANY );
// bind socket's name
nRet = bind( hSock, (sockaddr*)&saListen, sizeof(sockaddr) );
if( nRet == SOCKET_ERROR )
{
cout << "Failed to bind socket" << endl;
//shutdown( hSock );
closesocket( hSock );
return -1;
}
while( true )
{
cout << "Listening for connections" << endl;
// listen
nRet = listen( hSock, 5 ); // connection backlog queue set to 10
if( nRet == SOCKET_ERROR )
{
int nErr = WSAGetLastError();
if( nErr == WSAECONNREFUSED )
{
cout << "Failed to listen, connection refused" << endl;
}
else
{
cout << "Call to listen failed" << endl;
}
closesocket( hSock );
return -1;
}
// connect
sockaddr_in saClient = {0};
int nSALen = sizeof( sockaddr );
SOCKET hClient = accept( hSock, (sockaddr*)&saClient, &nSALen );
if( hClient == INVALID_SOCKET )
{
cout << "Invalid client socket, connection failed" << endl;
closesocket( hSock );
return -1;
}
cout << "Connection estabilished" << endl;
// process data
char wzRec[512] = {0};
int nLeft = 512;
int iPos = 0;
int nData = 0;
do
{
nData = recv( hClient, &wzRec[iPos], nLeft, 0 );
if( nData == SOCKET_ERROR )
{
cout << "Error receiving data" << endl;
memset( &wzRec, 0, sizeof( wzRec ) );
break;
}
nLeft -= nData;
iPos += nData;
} while( nLeft > 0 );
cout << "Data Recieved: " << wzRec << endl;
// echo data back to client
iPos = 0;
nLeft = 512;
do
{
nData = send( hClient, &wzRec[iPos], nLeft, 0 );
if( nData == SOCKET_ERROR )
{
cout << "Error sending data" << endl;
break;
}
nLeft -= nData;
iPos += nData;
} while( nLeft > 0 );
// close client connection
closesocket( hClient );
hClient = 0;
// perform a lowercase comparison
if( _stricmp( wzRec, "!shutdown" ) == 0 )
{
break;
}
// clear data buffer
memset( &wzRec, 0, sizeof( wzRec ) );
} // loop
cout << "Shutting down the server" << endl;
// close server socket
nRet = closesocket( hSock );
hSock = 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 << "Server is offline" << endl;
return 0;
}
---------------------client side------------------------------------
#include <winsock2.h>
#include <iostream>
#include <stdio.h>
//#include <tchar.h>
#include <windows.h>
#include <conio.h>
using namespace std;
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 )
{
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( 10000 );
//saServer.sin_addr.s_addr = inet_addr( "127.0.0.1" );
saServer.sin_addr.s_addr = inet_addr( "172.16.26.32" );
// 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;
// process data
char wzRec[1024] = "Hello from client no 1!!!";
int nLeft = 512;
int iPos = 0;
int nData = 0;
if( argc == 2 )
{
// copy input string from command argument
strcpy_s( wzRec, 1024, argv[1] );
}
do
{
nData = send( hServer, &wzRec[iPos], nLeft, 0 );
if( nData == SOCKET_ERROR )
{
cout << "Error sending data" << endl;
break;
}
nLeft -= nData;
iPos += nData;
} while( nLeft > 0 );
// clear data buffer
memset( &wzRec, 0, sizeof( wzRec ) );
nLeft = 512;
iPos = 0;
do
{
nData = recv( hServer, &wzRec[iPos], nLeft, 0 );
if( nData == SOCKET_ERROR )
{
cout << "Error receiving data" << endl;
break;
}
nLeft -= nData;
iPos += nData;
} while( nLeft > 0 );
cout << "Data Echoed: " << wzRec << endl;
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;
return 0;
getch;
}