Windows Sockets 2 and OpenCV

Hi !

I’m struggling managing TCP sockets with OpenCV. Each time I include the opencv libraries, I’m not able to connect from an external device (overflowing error in the accept function … socket error).

In the previous forum, there was some info … which didn’t work for me : https://answers.opencv.org/question/192653/opencv341-with-winsock2/

There is a Robot acting as a client which is going to ask some info to OpenCV, and OpenCV is the Server. Here the test code (I comment and uncomment the OpenCV libraries to check the results), Visual Studio 2019, x64, OpenCV 4.4.0 libraries :

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <WinSock2.h>
#include <Windows.h>
#include <sys/types.h>
#include <vector>
#include <sstream>
#include <fstream>
#include <stdio.h> 
#include <chrono>
#include <math.h>
#include <iphlpapi.h>
#include <WS2tcpip.h>
#include <string>
#pragma comment (lib, "ws2_32.lib")

using namespace std;
void openingSocket(int PORTServer, SOCKET& listening, SOCKET& clientSocket);
void closingSocket(SOCKET& Socket);
void clientConnection(int PORTServer, SOCKET& listening, SOCKET& clientSocket);
void informationSend(SOCKET clientSocket);

int main()
{

	int PORTServerVision = 4710; // 69 , 1001
	SOCKET listening, clientSocket;
	cout << "opening" << endl;
	BOOL executionandconnection = TRUE; 

	while (executionandconnection) {
		openingSocket(PORTServerVision, listening, clientSocket);
		clientConnection(PORTServerVision, listening, clientSocket);
		cout << "information send process" << endl;
		informationSend(clientSocket);
		cout << "closing" << endl;
		closingSocket(clientSocket);
	}
}

void openingSocket(int PORTServer, SOCKET& listening, SOCKET& clientSocket) {

	WSADATA wsData;
	WORD ver = MAKEWORD(2,0);

	int wsOk = WSAStartup(ver, &wsData);
	if (wsOk != 0)
	{
		cerr << "Can't Initialize winsock! Quitting" << endl;
		return;
	}

	// Create a socket

	listening = socket(AF_INET, SOCK_STREAM, 0);
	if (listening == INVALID_SOCKET)
	{
		cerr << "Can't create a socket! Quitting" << endl;
		return;
	}

	// Bind the ip address and port to a socket
	sockaddr_in hint;
	hint.sin_family = AF_INET;
	hint.sin_port = htons(PORTServer);
	hint.sin_addr.S_un.S_addr = INADDR_ANY; // Could also use inet_pton .... 

	bind(listening, (struct sockaddr*)&hint, sizeof(hint));

	// Tell Winsock the socket is for listening 
	listen(listening, 3);
}

void clientConnection(int PORTServer, SOCKET& listening, SOCKET& clientSocket) {

	// Wait for a connection
	sockaddr_in client;
	int clientSize = sizeof(client);
	//cout << "aqui" << endl;

	fd_set set;
	struct timeval timeout;
	int rv;
	FD_ZERO(&set); /* clear the set */
	FD_SET(listening, &set); /* add our file descriptor to the set */

	timeout.tv_sec = 5;
	timeout.tv_usec = 0;

	rv = select(listening + 1, &set, NULL, NULL, &timeout);

	if (rv == -1)
	{
		perror("select"); /* an error occurred */
		return;
	}
	else if (rv == 0)
	{
		printf("timeout occurred (5 second) \n"); /* a timeout occurred */
		return;
	}
	else
	{
		clientSocket = accept(listening, (struct sockaddr*)&client, &clientSize);
	}

	char host[NI_MAXHOST];		// Client's remote name
	char service[NI_MAXSERV];	// Service (i.e. port) the client is connect on

	ZeroMemory(host, NI_MAXHOST); // same as memset(host, 0, NI_MAXHOST);
	ZeroMemory(service, NI_MAXSERV);

	closesocket(listening);
}

void closingSocket(SOCKET& Socket) {

     closesocket(Socket);
     WSACleanup();

}

void informationSend(SOCKET clientSocket) {

	// While loop: accept and echo message back to client
	char buf[3000];

	string message = "(0.62462,0.18022)"; //X,Y,FOCUS
	ZeroMemory(buf, 3000);
	int sendResult = send(clientSocket, message.c_str(), message.size() + 1, 0);
}

Maybe the solution is obvious, but I don’t have enough experience in OpenCV.

Hope you can help me ! Have a nice day ! :slight_smile:

please elaborate on the error. where in the code does it happen, what exact errno/error message… is it…

please try this code without the opencv #includes, but with linking the opencv libraries. I need to know if the issue is causes by linking the libraries, or by the header files.

Hi crackwitz, regarding your request :

  1. The error happens in the accept function call (else case of rv = select(…)). It is a behavior error :

(I added two cout instructions of the clientSocket values before and after the accept call )

  • Without OpenCV #includes : I receive the values I want each time I connect. So normally, three digits for the socket values show me that it works.

  • With OpenCV #includes : Never able to get connected and receive the information. When I obtain the exact value of clientSocket, I get : 18446744073709551615.

  1. The behavior I explained in 1) happens with the linked libraries into the Visual Studio Projet (Both with and without #includes).

okay so the includes make a difference but not linking the library.

by the way, 18446744073709551615 is -1

the error doesn’t happen in accept, it happens in select. that is where the behavior diverges.

OpenCV apparently has a “select()” function. I think that could interfere. make sure to explicitly state the namespace that gives you the socket select. do not use using namespace cv;. that pollutes the global namespace.

I don’t think the socket APIs are namespaced… you can try if std::select exists.

Hi ! Actually neither select(…) nor accept(…) function belong to std namespace. They are from the Winsock2.h header.

HOWEVER, I found a related article regarding the bind function. There is an ambiguity between std:: bind(…) and ::bind global namespace.

So, I tried doing the same for the select(…) and the accept(…). I tried first with std (erasing the using namespace std instruction) and didn’t work, and then I changed from :

  • std::select(…) -> ::select()
  • std::accept(…) -> ::accept()

Guess what, it works ! :blush:

1 Like