0

I am relativily new to C++, therefore if the issue is basic I am sorry.

Problem

I am attempting to build a socket server which will soon be used to stream a video feed. When I build the server using g++ server.cpp -o server I can seen the buffer being sent from the client. However the moment I switch to building the project using CMake & make the client can not connect to the server socket. Do you know what maybe causing this issue? It only seems to happen when the server.cpp is built using make.

Please see the code for the server.cpp, client.cpp and the CMakeLists.txt below.

server.cpp

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <iostream>
#include "opencv2/opencv.hpp"

using namespace std;
using namespace cv;

int main() {
  
  int port = 30015;
  int server = 0, client = 0; 
  struct sockaddr_in serverAddr;

  server  = socket(AF_INET, SOCK_STREAM, 0);
  serverAddr.sin_addr.s_addr = INADDR_ANY;
  serverAddr.sin_family = AF_INET;
  serverAddr.sin_port = htons(port);

  bind(server, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
  listen(server, 0);

  cout << "Listening for incoming connetions... :) " << " port: " << port << endl;

  char buffer[1024] = { 0 };
  
  while (1) {
    client = accept(server, (struct sockaddr*)NULL, NULL);

    cout << "Client Connected" << endl;
    
    if (client < 0) break;

    
    read(client, buffer, sizeof(buffer) - 1);
    cout << "Client says: buffer is " << buffer << endl;
    memset(buffer, 0, sizeof(buffer));
    close(client);
    cout << "Client Disconnected" << endl;  
  }
  
  cout << "Server Disconnected" << endl;
  return 0;
}

client.cpp

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
#include <iostream>
#include "opencv2/opencv.hpp"

using namespace std;
using namespace cv;

int main() {
  char* sip = "127.0.0.1";
  int port = 30015;
  int serverSock = 0;
  struct sockaddr_in addr;
  serverSock = socket(AF_INET, SOCK_STREAM, 0);

  addr.sin_addr.s_addr = inet_addr(sip);
  addr.sin_family = AF_INET;
  addr.sin_port = htons(port);

  cout << "Connecting to server: " << sip << " port: " << port << endl;

  if (connect(serverSock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
    cout << "failed to connect to server" << endl;
    exit(1);
  }

  cout << "Connected to the server?!" << endl;
  char buffer[1024] = {'h', 'e', 'l', 'l', 'o', '.'};
  write(serverSock, buffer, strlen(buffer));

  cout << "Message sent! With buffer in Client." << buffer << endl;

  close(serverSock);

  cout << "Socket Closed." << endl;
}

CMakeLists.txt (this is the same for both server and client however the project name and file path is different)

# CMakeLists.txt

# Older versions of CMake are likely to work just fine but, since
# I don't know where to cut off I just use the version I'm using
cmake_minimum_required(VERSION "3.17")

# name of this example project
project(serverSocket)

# set OpenCV_DIR variable equal to the path to the cmake
# files within the previously installed opencv program
set(OpenCV_DIR /usr/local/include/)

# Tell compiler to use C++ 14 features which is needed because
# Clang version is often behind in the XCode installation
set(CMAKE_CXX_STANDARD 14)

# configure the necessary common CMake environment variables
# needed to include and link the OpenCV program into this
# demo project, namely OpenCV_INCLUDE_DIRS and OpenCV_LIBS
find_package( OpenCV REQUIRED )

# tell the build to include the headers from OpenCV
include_directories( ${OpenCV_INCLUDE_DIRS} )

# specify the executable target to be built
add_executable(serverSocket server.cpp)

# tell it to link the executable target against OpenCV
target_link_libraries(serverSocket ${OpenCV_LIBS} )
user4581301
  • 33,082
  • 7
  • 33
  • 54
Matt Hammond
  • 765
  • 1
  • 7
  • 25
  • 1
    `bind(server, (struct sockaddr*)&serverAddr, sizeof(serverAddr));` No check for success. `listen(server, 0);` no check for success. Also no check for success at `read(client, buffer, sizeof(buffer) - 1);`, but that'll come later. If you check for success and get failure diagnostics from `errno` or `perror` you may still get surprises, but at least you have some idea what they were. – user4581301 Dec 22 '20 at 17:47
  • @user4581301, I just added the error checks (... < 0) to bind, listen and accept. Whilst I did not get any errors, I now see the messages and the connection is a success :/ very weird? – Matt Hammond Dec 22 '20 at 17:55
  • `listen(server, 0);` is a bit weird--listen for a maximum of 0 connection attempts? I'll see if I can dig up an explanation, but it shouldn't cause the trouble you were seeing, and certainly not intermittently.. – user4581301 Dec 22 '20 at 18:06
  • @user4581301, I have now updated the listen number of connection. I was following a tutorial as I have previous experience with Python sockets, yet this is my first time using c++ sockets(very similar). The tutorial set it to listen(server, 0) and I assumed maybe this was removing the max cap. – Matt Hammond Dec 22 '20 at 18:11
  • [Listen manpage](https://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html) has a good description of what you should get from 0 on a POSIX-compliant OS. Sadly that's pretty much no guarantees. I hate it when they do that. Grrrr.... A specification that doesn't specify. The behaviour I'm used to is the OS jacks 0 up to some defined minimum, but now I'm seeing you could get anything. – user4581301 Dec 22 '20 at 18:11
  • @user4581301, yeah thats very weird. 'may allow'! Therefore I think it is best if I never use 0 again :). – Matt Hammond Dec 22 '20 at 18:17
  • Unrelated: TCP guarantees data arrives... eventually. That "eventually" is murder on a realtime data feed like streaming video. Typically streaming video is sent in relatively small datagrams (protocols based on UDP). If a packet is lost, no one cares because A) it's small and easily interpolated and B) by the time it could be retransmitted, the missing data probably would no longer be required as th frame it belongs to has long since been shown. – user4581301 Dec 22 '20 at 18:18
  • The socket interface's implementation notes (probably bundled in with the OS) should specify exactly what happens with a 0, same as [Implementation Defined Behaviour](https://stackoverflow.com/questions/2397984) in the C++ Standard, but implementation-defined means not portable so use with caution. – user4581301 Dec 22 '20 at 18:24
  • @user4581301, thank you for the UDP advice. I've just done some research and sounds perfect for what I need! You hero! – Matt Hammond Dec 22 '20 at 18:28

0 Answers0