I am trying to to learn how to stream image frames via UDP in C and I was following this tutorial for the server part to receive my frames, this tutorial clearly uses code from question stackoverflow question. However, after following up both sources, whenever I attempt to load my libraries in geany/c :
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace std;
using namespace cv;
#define width 320
#define height 240
int imgSize;
int bytes=0;
bool running = true;
char key;
const int ah = 230400;
int main(int argc, char * argv[]) {
SOCKET server;
SOCKADDR_IN addr;
server = socket(AF_INET, SOCK_STREAM, 0);
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_family = AF_INET;
addr.sin_port = htons(9999);
connect(server, (SOCKADDR *)&addr, sizeof(addr));
return 0;
}
This gives me the following errors:
/home/pi/Documentos/cam.cpp: In function ‘int main(int, char**)’:
/home/pi/Documentos/cam.cpp:27:2: error: ‘SOCKET’ was not declared in this scope
27 | SOCKET server;
| ^~~~~~
/home/pi/Documentos/cam.cpp:28:2: error: ‘SOCKADDR_IN’ was not declared in this scope
28 | SOCKADDR_IN addr;
| ^~~~~~~~~~~
/home/pi/Documentos/cam.cpp:29:2: error: ‘server’ was not declared in this scope; did you mean ‘servent’?
29 | server = socket(AF_INET, SOCK_STREAM, 0);
| ^~~~~~
| servent
/home/pi/Documentos/cam.cpp:30:2: error: ‘addr’ was not declared in this scope
30 | addr.sin_addr.s_addr = inet_addr("127.0.0.1");
| ^~~~
/home/pi/Documentos/cam.cpp:30:25: error: ‘inet_addr’ was not declared in this scope; did you mean ‘in6_addr’?
30 | addr.sin_addr.s_addr = inet_addr("127.0.0.1");
| ^~~~~~~~~
| in6_addr
/home/pi/Documentos/cam.cpp:33:19: error: ‘SOCKADDR’ was not declared in this scope
33 | connect(server, (SOCKADDR *)&addr, sizeof(addr));
| ^~~~~~~~
/home/pi/Documentos/cam.cpp:33:29: error: expected primary-expression before ‘)’ token
33 | connect(server, (SOCKADDR *)&addr, sizeof(addr));
Forgive my ignorance, I'd like to know what is the right way to create a UDP socket for a specific IP/Port
CodePudding user response:
You are using SOCKET
or SOCKADDR_IN
which is Microsoft dedicated but I see Linux headers.
You need to select what you want to do:
- You need code only for Windows.
- You need code only for Linux.
- You need a cross-platform code.
Your approach somehow differs based on what you want to do.
If your code is supposed to work on Windows only, replace:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
with:
#include <windows.h>
#include <winsock2.h>
and also add WSAStartup()
and WSACleanup()
to your code (I'm almost sure you will miss this part if you are socket programming on Windows). You also need to link your code with Ws2_32.lib
.
If you are coding for Linux, replace SOCKET
with int
, SOCKADDR_IN
with sockaddr_in
, and SOCKADDR
with sockaddr
and try again.
CodePudding user response:
That's WinSock code. And techniques and functions available there aren't 100% matching between POSIX and WinSock. I wouldn't recommend to define own version of Windows types, that would be misleading and hard to see which part of code were refactored. Rather go with something like:
#ifdef WINDOWS_PC /** some predefined macro */
typedef SOCKET socket_t;
#else
# ifdef POSIX /** some predefined macro */
typedef int socket_t;
# endif
#endif
POSIX-compatible types relevant to SOCKADDR_IN
and SOCKADDR
were sockaddr_in
and sockaddr
, they were to be available in WinSock2.
WinSock functionality uses a special function for getting error codes instead of errno
which is used in POSIX. There is no ioctl
in Winsock function, instead there is not quite same ioctlsocket
, Windows closesocket
would be replaced just by close
because POSIX socket is either a file(stream) or block device, read
/write
can be used on it.