I'm running into some issues compiling and I'm not sure why. I get a multiple definition error for a few things, however, as far as I'm aware, I only define them once. I'm confused as to why this is happening and where these definitions are happening and why its not working. I'm not that familiar with C++ so I'm not sure what I'm doing wrong here and would appreciate some assistance.
make
/usr/bin/g++ -c -o object/author.o src/author.cpp -g -I./include
/usr/bin/g++ -o ---- object/connection_manager.o object/author.o. object/control_header_lib.o object/network_util.o object/main.o object/control_handler.o -g -I./include
object/main.o:(.bss+0x4): multiple definition of `control_socket'
object/connection_manager.o:(.bss+0x104): first defined here
object/main.o: In function `main':
/home/Documents/---/src/main.cpp:9: multiple definition of `router_socket'
object/connection_manager.o:/home/Documents/---/src. /connection_manager.cpp:35: first defined here
object/main.o: In function `main':
/home/Documents/---/src/main.cpp:9: multiple definition of `data_socket'
object/connection_manager.o:/home/Documents/---/src. /connection_manager.cpp:35: first defined here
object/control_handler.o:(.bss+0x0): multiple definition of `CONTROL_PORT'
object/main.o:/home/Documents/---/src/main.cpp:9: first defined here
object/connection_manager.o: In function `main_loop()':
/home/Documents/---/src/connection_manager.cpp:33: undefined reference to `new_control_conn(int)'
/home/Documents/---/src/connection_manager.cpp:54: undefined reference to `isControl(int)'
/home/Documents/---/src/connection_manager.cpp:56: undefined reference to `control_recv_hook(int)'
collect2: error: ld returned 1 exit status
Makefile:19: recipe for target '----' failed
make: *** [----] Error 1
main.cpp
#include "../include/global.h"
#include "../include/connection_manager.h"
using namespace std;
int sockfd;
int main(int argc, char **argv)
{
if(argc != 2){
ERROR("Incorrect number of args...\n");
}
printf("control port: %d\n", atoi(argv[1]));
sscanf(argv[1], "%" SCNu16, &CONTROL_PORT);
init();
return 0;
}
global.h
#ifndef GLOBAL_H_
#define GLOBAL_H_
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#define ERROR(err_msg) {perror(err_msg); exit(EXIT_FAILURE);}
#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
#endif
connection_manager.cpp
#include <sys/select.h>
#include "../include/connection_manager.h"
#include "../include/global.h"
#include "../include/control_handler.h"
int control_socket, router_socket, data_socket;
void init()
{
control_socket = create_control_sock();
}
connection_manager.h
#ifndef CONNECTION_MANAGER_H_
#define CONNECTION_MANAGER_H_
void init();
#endif
control_handler.cpp
#include <sys/socket.h>
#include <netinet/in.h>
#include <strings.h>
#include <sys/queue.h>
#include <unistd.h>
#include <string.h>
#include <list>
#include "../include/global.h"
#include "../include/network_util.h"
#include "../include/control_header_lib.h"
#include "../include/author.h"
#ifndef PACKET_USING_STRUCT
#define CNTRL_CONTROL_CODE_OFFSET 0x04
#define CNTRL_PAYLOAD_LEN_OFFSET 0x06
#endif
struct ControlConn // linked list for active control connections
{
int sockfd;
// ..
}*connection, *conn_temp;
std::list<ControlConn> control_conn_list;
int create_control_sock()
{
int sock;
struct sockaddr_in control_addr;
socklen_t addrlen = sizeof(control_addr);
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0){
ERROR("Failed to create socket...\n");
}
bzero(&control_addr, addrlen);
control_addr.sin_family = AF_INET;
control_addr.sin_addr.s_addr = htonl(INADDR_ANY);
control_addr.sin_port = htons(CONTROL_PORT);
if (bind(sock, (struct sockaddr *)&control_addr, addrlen) < 0){
ERROR("Bind failed...");
}
if (listen(sock, 5) < 0){
ERROR("Listen failed...");
}
return sock;
}
control_handler.h
#ifndef CONTROL_HANDLER_H_
#define CONTROL_HANDLER_H_
int create_control_sock();
int new_control_conn(int sock_index);
bool isControl(int sock_index);
bool control_recv_hook(int sock_index);
#endif
In header file you need to just declare variable:
extern uint16_t CONTROL_PORT;
Then in corresponding cpp (global.cpp) file you should define it:
uint16_t CONTROL_PORT;
Related
When I tried to compile my game; and it says like
Networking/Sockets/Socket.hpp:18:81: error: expected identifier before ')' token
so if you want to see the source code I've in github here the link:
https://github.com/suky637/ServerPlusPlus
for peaple that do not want to go to github I will send you the Socket.hpp (this is the main error source) the code:
#ifndef Socket_hpp
#define Socket_hpp
#include <stdio.h>
#include <WinSock2.h>
#include <winsock.h>
#include <iostream>
namespace spp
{
class Socket {
private:
struct sockaddr_in address;
int sock;
int connection;
public:
// Constructor
Socket(int domain, int service, int protocol, int port, u_long interface_parameter);
// Virtual function to confirm to connect to the network
virtual int connect_to_network(int sock, struct sockaddr_in address) = 0;
// Function to test sockets and connection
void test_connection(int);
// Getter function
struct sockaddr_in get_address();
int get_sock();
int get_connection();
// Setter function
void set_connection(int connection_);
};
}
#endif
oh and this is the output:
// command : g++ Server.cpp -o ServerPlusPlus
In file included from Networking/Sockets/_ServerPlusPlus-sockets.hpp:6:0,
from Networking/ServerPlusPlus-Networking.hpp:6,
from ServerPlusPlus.hpp:6,
from Server.cpp:1:
Networking/Sockets/Socket.hpp:19:81: error: expected identifier before ')' token
Socket.cpp
#include "Socket.hpp"
// Default constructor
spp::Socket::Socket(int domain,
int service,
int protocol,
int port,u_long interface_parameter,
)
{
// Define address structure
address.sin_family = domain;
address.sin_port = port;
address.sin_addr.s_addr = htonl(interface_parameter);
// Establish socket
sock = socket(domain,service,protocol);
test_connection(sock);
// Establish Connection
connection = connect_to_network(sock, address);
test_connection(connect_to_network);
}
// Test Connection virtual function
void spp::Socket::test_connection(int item_to_test)
{
// Comfirm that the socket or connection has bin properly established
if (item_to_test < 0)
{
perror("Failed To Connect...");
exit(EXIT_FAILURE);
}
}
// Getter functions
struct sockaddr_in spp::Socket::get_address()
{
return address;
}
int spp::Socket::get_sock()
{
return sock;
}
int spp::Socket::get_connection()
{
return connection;
}
// Setter functions
void spp::Socket::set_connection(int connection_)
{
connection = connection_;
}
the main funtion where I compile is
#include "ServerPlusPlus.hpp"
using namespace std;
int main()
{
cout << "*--------- Starting ---------*" << endl;
cout << "* Binding Socket... ";
spp::BindingSocket bs = spp::BindingSocket(AF_INET,SOCK_STREAM,0,80,INADDR_ANY);
cout << "Complete\n* Listening Socket... ";
spp::ListeningSocket ls = spp::ListeningSocket(AF_INET, SOCK_STREAM, 0, 80, INADDR_ANY, 10);
cout << "Complete\n\n\n* Sucess!" << endl;
system("pause");
}
probably it is the file I copile and ServerPlusPlus.hpp is
#ifndef ServerPlusPlus
#define ServerPlusPlus
#include <stdio.h>
#include "Networking/ServerPlusPlus-Networking.hpp"
#endif
and ServerPlusPlus-Networking.hpp
#ifndef ServerPlusPlus_Networking_hpp
#define ServerPlusPlus_Networking_hpp
#include <stdio.h>
#include "Sockets/_ServerPlusPlus-sockets.hpp"
#endif
and ServerPlusPlus_Sockets_hpp
#ifndef ServerPlusPlus_Sockets_hpp
#define ServerPlusPlus_Sockets_hpp
#include <stdio.h>
#include "Socket.hpp"
#include "BindingSocket.hpp"
#include "ListeningSocket.hpp"
#include "ConnectingSocket.hpp"
#endif
You seem to have missed that actual answer.
interface is used as a typedef in some windows headers
see What is the "interface" keyword in MSVC?
change the name to iface or something like that
I'm getting the error undefined reference to i2c_smbus_read_word_data(int, unsigned char)`
I've tried wrapping a few of my libraries in extern "C" but I get the same error. I tried this after seeing this answer to a similar problem.
Regardless of whether I wrap some or all of these include #include <linux/i2c-dev.h>, #include <i2c/smbus.h>, #include <linux/i2c.h>, #include <sys/ioctl.h> statements I get the same error.
The error is i2c_read.cpp:(.text+0xf8): undefined reference to i2c_smbus_read_word_data(int, unsigned char)'
collect2: error: ld returned 1 exit status`
I am running my command $g++ i2c_read.cpp -li2c with -li2c as you can see.
extern "C" {
#include <linux/i2c-dev.h>
#include <i2c/smbus.h>
}
#include <linux/i2c.h>
#include <sys/ioctl.h>
#include <fcntl.h> /* For O_RDWR */
#include <unistd.h>
#include <iostream>
using namespace std;
int file;
int adapter_nr = 2;
char filename[20];
int main() {
cout << filename << 19 << "/dev/i2c-1" << adapter_nr;
file = open(filename, O_RDWR);
if (file < 0) {
exit(1);
}
int addr = 0x74;
if (ioctl(file, I2C_SLAVE, addr) < 0) {
exit(1);
}
__u8 reg = 0x40;
__s32 res;
char buf[10];
res = i2c_smbus_read_word_data(file, reg);
if (res < 0) {
/* ERROR HANDLING: i2c transaction failed */
} else {
/* res contains the read word */
}
buf[0] = reg;
buf[1] = 0x42;
buf[2] = 0x43;
if (write(file, buf, 3) != 3) {
/* ERROR HANDLING: i2c transaction failed */
}
}
I did a sudo apt-get update and the problem went away.
I also ran a few commands to update the compiler, though it still says my g++ version is 7.5, so that might have also contributed.
Hi I'm using visual studio 2017 and I received that error when I compiled live555 sub-project groupsock, "fatal error C1083: Cannot open include file: 'ifaddrs.h': No such file or directory.I don't know how to deal with the problem.How do solve this problem?thanks!
GroupsockHelper.cpp header content
#include "GroupsockHelper.hh"
#if (defined(__WIN32__) || defined(_WIN32)) && !defined(__MINGW32__)
#include <time.h>
extern "C" int initializeWinsockIfNecessary();
#else
#include <stdarg.h>
#include <time.h>
#include <sys/time.h>
#if !defined(_WIN32)
#include <netinet/tcp.h>
#ifdef __ANDROID_NDK__
#include <android/ndk-version.h>
#define ANDROID_OLD_NDK __NDK_MAJOR__ < 17
#endif
#endif
#include <fcntl.h>
#define initializeWinsockIfNecessary() 1
#endif
#if defined(__WIN32__) || defined(_WIN32) || defined(_QNX4)
#else
#include <signal.h>
#define USE_SIGNALS 1
#endif
#ifndef NO_GETIFADDRS
#include <ifaddrs.h>
#include <net/if.h>
#endif
#include <stdio.h>
// By default, use INADDR_ANY for the sending and receiving interfaces (IPv4 only):
ipv4AddressBits SendingInterfaceAddr = INADDR_ANY;
ipv4AddressBits ReceivingInterfaceAddr = INADDR_ANY;
static void socketErr(UsageEnvironment& env, char const* errorMsg) {
env.setResultErrMsg(errorMsg);
}
NoReuse::NoReuse(UsageEnvironment& env)
: fEnv(env) {
`enter code here`groupsockPriv(fEnv)->reuseFlag = 0;
}
NoReuse::~NoReuse() {
groupsockPriv(fEnv)->reuseFlag = 1;
reclaimGroupsockPriv(fEnv);
}
.......
I am trying to understand the nature of getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen).
I am trying to see the initial status of SO_DEBUG and I am referring to this link https://www.mkssoftware.com/docs/man3/getsockopt.3.asp , and I am not sure if I am doing this the correct way because I am getting random values.
//***********************************************Libraries****************************************************************
#include <iostream>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <errno.h>
using namespace std;
//************************************************************************************************************************
int main()
{
int * optval;
int optionDebug = 0;
socklen_t optlen;
int sockFD;
sockFD = socket(AF_INET, SOCK_STREAM ,0);
optlen =sizeof(optval);
int udpFD;
udpFD = socket(AF_INET, SOCK_DGRAM,0);
optionDebug = getsockopt(sockFD, SOL_SOCKET, SO_DEBUG, optval, &optlen) ;
cout<<"My value "<< *optval<<endl;
return 0;
}
To retrieve the value for optval you need to pass the address of a valid variable (not an uninitialized pointer):
ExpectedOptType optval;
// ^^^^^^^^^^^^^^^ Put whatever type (probably a enum) is expected for
// the specific option
optionDebug = getsockopt(sockFD, SOL_SOCKET, SO_DEBUG, &optval, &optlen);
// ^
Read more details about how it works here: getsockopt(2).
I have a project where I need to create a secure http server in C/C++ on Linux and I've chosen to use openssl, however, when I try to include the applinker.c from their github I see a lot of errors, mostly because the file seems to be written for Windows.I would like to know if there is an alternative for Linux or how should I deal with this.
Here is the applinker.c code:
/*
* Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#define APPLINK_STDIN 1
#define APPLINK_STDOUT 2
#define APPLINK_STDERR 3
#define APPLINK_FPRINTF 4
#define APPLINK_FGETS 5
#define APPLINK_FREAD 6
#define APPLINK_FWRITE 7
#define APPLINK_FSETMOD 8
#define APPLINK_FEOF 9
#define APPLINK_FCLOSE 10 /* should not be used */
#define APPLINK_FOPEN 11 /* solely for completeness */
#define APPLINK_FSEEK 12
#define APPLINK_FTELL 13
#define APPLINK_FFLUSH 14
#define APPLINK_FERROR 15
#define APPLINK_CLEARERR 16
#define APPLINK_FILENO 17 /* to be used with below */
#define APPLINK_OPEN 18 /* formally can't be used, as flags can vary */
#define APPLINK_READ 19
#define APPLINK_WRITE 20
#define APPLINK_LSEEK 21
#define APPLINK_CLOSE 22
#define APPLINK_MAX 22 /* always same as last macro */
#ifndef APPMACROS_ONLY
# include <stdio.h>
# include <io.h>
# include <fcntl.h>
static void *app_stdin(void)
{
return stdin;
}
static void *app_stdout(void)
{
return stdout;
}
static void *app_stderr(void)
{
return stderr;
}
static int app_feof(FILE *fp)
{
return feof(fp);
}
static int app_ferror(FILE *fp)
{
return ferror(fp);
}
static void app_clearerr(FILE *fp)
{
clearerr(fp);
}
static int app_fileno(FILE *fp)
{
return _fileno(fp);
}
static int app_fsetmod(FILE *fp, char mod)
{
return _setmode(_fileno(fp), mod == 'b' ? _O_BINARY : _O_TEXT);
}
#ifdef __cplusplus
extern "C" {
#endif
__declspec(dllexport)
void **
# if defined(__BORLANDC__)
/*
* __stdcall appears to be the only way to get the name
* decoration right with Borland C. Otherwise it works
* purely incidentally, as we pass no parameters.
*/
__stdcall
# else
__cdecl
# endif
OPENSSL_Applink(void)
{
static int once = 1;
static void *OPENSSL_ApplinkTable[APPLINK_MAX + 1] =
{ (void *)APPLINK_MAX };
if (once) {
OPENSSL_ApplinkTable[APPLINK_STDIN] = app_stdin;
OPENSSL_ApplinkTable[APPLINK_STDOUT] = app_stdout;
OPENSSL_ApplinkTable[APPLINK_STDERR] = app_stderr;
OPENSSL_ApplinkTable[APPLINK_FPRINTF] = fprintf;
OPENSSL_ApplinkTable[APPLINK_FGETS] = fgets;
OPENSSL_ApplinkTable[APPLINK_FREAD] = fread;
OPENSSL_ApplinkTable[APPLINK_FWRITE] = fwrite;
OPENSSL_ApplinkTable[APPLINK_FSETMOD] = app_fsetmod;
OPENSSL_ApplinkTable[APPLINK_FEOF] = app_feof;
OPENSSL_ApplinkTable[APPLINK_FCLOSE] = fclose;
OPENSSL_ApplinkTable[APPLINK_FOPEN] = fopen;
OPENSSL_ApplinkTable[APPLINK_FSEEK] = fseek;
OPENSSL_ApplinkTable[APPLINK_FTELL] = ftell;
OPENSSL_ApplinkTable[APPLINK_FFLUSH] = fflush;
OPENSSL_ApplinkTable[APPLINK_FERROR] = app_ferror;
OPENSSL_ApplinkTable[APPLINK_CLEARERR] = app_clearerr;
OPENSSL_ApplinkTable[APPLINK_FILENO] = app_fileno;
OPENSSL_ApplinkTable[APPLINK_OPEN] = _open;
OPENSSL_ApplinkTable[APPLINK_READ] = _read;
OPENSSL_ApplinkTable[APPLINK_WRITE] = _write;
OPENSSL_ApplinkTable[APPLINK_LSEEK] = _lseek;
OPENSSL_ApplinkTable[APPLINK_CLOSE] = _close;
once = 0;
}
return OPENSSL_ApplinkTable;
}
#ifdef __cplusplus
}
#endif
#endif
And here is a little snippet I prepared for testing the connection:
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <cstring>
#include <cstdlib>
#include <cerrno>
#include <arpa/inet.h>
#include <cstdio>
#include <sys/stat.h>
#include <unordered_map>
#include <string>
#include <algorithm>
#include <fstream>
#include <thread>
#include "openssl-master/ms/applink.c"
#include "openssl-master/include/openssl/bio.h"
#include "openssl-master/include/openssl/ssl.h"
#include "openssl-master/include/openssl/err.h"
#define PORT 2024
void InitializeSSL()
{
SSL_load_error_strings();
SSL_library_init();
OpenSSL_add_all_algorithms();
}
void DestroySSL()
{
ERR_free_strings();
EVP_cleanup();
}
void ShutdownSSL(SSL *ssl)
{
SSL_shutdown(ssl);
SSL_free(ssl);
}
int main(int argc, const char * argv[]) {
int sockfd, newsockfd;
SSL_CTX *sslctx;
SSL *cSSL;
InitializeSSL();
struct sockaddr_in server;
struct sockaddr_in from;
SSL_CTX_set_options(sslctx, SSL_OP_SINGLE_DH_USE);
int use_cert = SSL_CTX_use_certificate_file(sslctx, "/serverCertificate.pem" , SSL_FILETYPE_PEM);
int use_prv = SSL_CTX_use_PrivateKey_file(sslctx, "/serverCertificate.pem", SSL_FILETYPE_PEM);
int sd;
if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
{
perror ("socket() error.\n");
return errno;
}
bzero (&server, sizeof (server));
bzero (&from, sizeof (from));
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl (INADDR_ANY);
server.sin_port = htons (PORT);
if (bind (sd, (struct sockaddr *) &server, sizeof (struct sockaddr)) == -1)
{
perror ("bind() error.\n");
return errno;
}
if (listen (sd, 5) == -1)
{
perror ("listen() error.\n");
return errno;
}
int client;
socklen_t length = sizeof (from);
printf ("Waiting on port %d...\n",PORT);
fflush (stdout);
client = accept (sd, (struct sockaddr *) &from, &length);
if (client < 0)
{
perror ("accept() error.\n");
return 0;
}
cSSL = SSL_new(sslctx);
SSL_set_fd(cSSL, client);
int ssl_err = SSL_accept(cSSL);
if(ssl_err <= 0)
{
ShutdownSSL(cSSL);
}
return 0;
}
And I compile it like this: g++ withssl.cpp libssl.a libcrypto.a -lssl -lcrypto -o server.bin
Code looks good, I used Suse Leap 4.2.2 and performed these commands:
openssl version
OpenSSL 1.0.2j-fips 26 Sep 2016
sudo zypper in openssl-devel
g++ -std=c++11 main.cpp -lssl -lcrypto -o server
Because I am using the distro provided openssl I changed your code to include the standard headers like this:
#include <openssl/ssl.h>
#include <openssl/err.h>
// DONT NEED
// suggest instead of including C code, link to the libraries
// for example, /usr/lib64/libssl.so contains referenced functions
// observe the provided functions using a command like this
// readelf -a /usr/lib64/libssl.so | grep FUNC
// #include "openssl-master/ms/applink.c"
// WRONG PATH?
// suggest you use a distro provided openssl instead of building your own
// #include "openssl-master/include/openssl/bio.h"
// #include "openssl-master/include/openssl/ssl.h"
// #include "openssl-master/include/openssl/err.h"