C-Socket Programming-"undefined reference" - c

I am a beginner in socket programming in C. I got the code in the book and when I compiled, these are following error with undefined reference. Please give a tips to correct this!Thank you!
Code:
#include <stdio.h>
#include <winsock.h>
#include <winsock2.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define RCVBUFSIZE 32
int main(int argc, char *argv[]){
int sock;
struct sockaddr_in echoServAddr;
unsigned short echoServPort;
char *servIP;
char *echoString;
char echoBuffer[RCVBUFSIZE];
unsigned int echoStringLen;
int bytesRcvd, totalBytesRcvd;
if(argc>3 || argc>4){
printf("Usage: %s <Server IP> <Echo Word> [<Echo Port>\n",argv[0]);
exit(1);
}
servIP=argv[1];
echoString=argv[2];
if(argc==4){
echoServPort=atoi(argv[3]);
}
else{
echoServPort=7;
}
if((sock=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP))<0){
printf("socket() failed!");
}
memset(&echoServAddr,0,sizeof(echoServAddr));
echoServAddr.sin_family=AF_INET;
echoServAddr.sin_addr.s_addr=inet_addr(servIP);
echoServAddr.sin_port=htons(echoServPort);
if (connect(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0){
printf("connect() failed!");
}
echoStringLen=strlen(echoString);
if(send(sock,echoString, echoStringLen,0)!=echoStringLen){
printf("send() send maximum bytes than expected");
}
totalBytesRcvd=0;
printf("Received");
while(totalBytesRcvd<echoStringLen){
if((bytesRcvd=recv(sock,echoBuffer,RCVBUFSIZE-1,0))<=0){
printf("recv() failed!");
}
totalBytesRcvd+=bytesRcvd;
echoBuffer[bytesRcvd]='\0';
printf(echoBuffer);
}
close(sock);
exit(1);
}
I got errors as follow:
In function `main':
client.cpp:34: undefined reference to `_socket#12'
client.cpp:39: undefined reference to `_inet_addr#4'
client.cpp:40: undefined reference to `_htons#4'
client.cpp:41: undefined reference to `_connect#12'
client.cpp:45: undefined reference to `_send#16'
client.cpp:51: undefined reference to `_recv#16'
collect2.exe [Error] ld returned 1 exit status

From my observation, you're trying to build Winsock application with MinGW.
MinGW, by default, don't link Winsock library (which is Ws2_32.lib) automatically, so you need to manually tell compiler by using -l flag plus name of your library.
gcc winsock.c -o winsock.exe -lws2_32
Edit : If you're IDE which are using MinGW suite (Code::Block, DevC++, etc), you can try to find option where you can manually add compiler flags, and add -lws2_32 into on of your compiler flag
Edit : Based on your comment above, so you're using Dev-C++ IDE, below is guide how you can use ws2_32.lib library inside your IDE
Go to top menu Tools, and click Compiler Options...
Inside Compiler Options, tick checkbox Add the following commands when calling the compiler
Put compiler flag -lws2_32 below into the textarea
Press OK
Try again to compile your source code. If nothing go wrong, your program should be compiled successfully.
Regards

Related

C undefined reference to InetPtonW

I'm trying to use InetPtonW:
if(InetPtonW(AF_INET, argv[1], &ThisSenderInfo.sin_addr)<=0) {
return 1;
}
However I get the following message when compiling:
warning: implicit declaration of function 'InetPtonW' [-Wimplicit-function-declaration]
undefined reference to `InetPtonW'
collect2.exe: error: ld returned 1 exit status
I've read the documentation located here and I've followed everything but still can't get it to work.
• I'm compiling with Ws2_32 library gcc test.c -o test -lws2_32 using MinGW
• I've included the needed header files #include <ws2tcpip.h> and #include <windows.h>
• I've tried using InetPton but it returns the same error
• Running on Windows 10
I recall running into this exact issue some many months ago. #alk's comment points to a question whose accepted answer feels very similar to what fixed it for me.
You should be able to #define a version macro (or two) before your #include lines to fix it.
While I feel strongly that the aforementioned answer is correct, I'll update this answer later today when I can verify.
Update!
The code I was referencing above doesn't have InetPtonW in it anymore but it had the necessary #defines in it. Here's a brief example that compiles on my machine (win10/mingw64/gcc 8.2.0):
Z:\Some\Directory>gcc test.c -o test -lmswsock -lws2_32
#define NTDDI_VERSION NTDDI_VISTA
#define WINVER _WIN32_WINNT_VISTA
#define _WIN32_WINNT _WIN32_WINNT_VISTA
#include <winsock2.h>
#include <Ws2tcpip.h>
#include <stdio.h>
/* This is "test.c", please pardon the lack of error checking. */
int main(void) {
BYTE ipbuf[4] = {0};
WSADATA wsa;
WSAStartup(MAKEWORD(2,2), &wsa);
printf("%d: ", InetPtonW(AF_INET, L"127.0.0.1", &ipbuf));
for(int i = 0; i < 4; ++i)
printf("%hhu.", ipbuf[i]);
WSACleanup();
}
Output should look like:
Z:\Some\Directory>gcc test.c -o test -lmswsock -lws2_32
Z:\Some\Directory>test
1: 127.0.0.1.
Z:\Some\Directory>
It's a linking error. which say that, included library path, the given function not found. please make sure your dll library path for InetPtonW or make sure that is available in your system or not.

Linker error with intercepting function calls in GCC

I am using the standard __wrap_function and __real_function to intercept function calls with -Wl,--wrap=function. This works successfully for most functions like malloc, fopen, etc. However, I am unable to wrap these two functions:
int connect(int, const struct sockaddr*, socklen_t)
int stat(const char*, struct stat*)
With these functions, the linker complains with undefined reference to __real_connect and __real_stat.
Is there any particular reason for this? (Note: I can also wrap socket functions for example)
It is likely you forgot to add -Wl,--wrap=connect and -Wl,--wrap=stat to your link line.
This works for me:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <unistd.h>
int __wrap_connect (int s, const struct sockaddr *addr, socklen_t len)
{
puts(__func__);
return __real_connect(s, addr, len);
}
int __wrap_stat (const char *path, struct stat *buf)
{
puts(__func__);
return __real_stat(path, buf);
}
int main(void) {
connect(0, NULL, 0);
stat("/", 0);
return 0;
}
When compiled on my system.
$ uname -s -r
Linux 2.6.32-696.16.1.el6.x86_64
$ gcc --version | grep gcc
gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-18)
$ gcc c.c -Wl,--wrap=connect -Wl,--wrap=stat
$
However, when leaving off -Wl,--wrap=stat, for example, I get:
$ gcc c.c -Wl,--wrap=connect
/tmp/cchVzvsE.o: In function `__wrap_stat':
c.c:(.text+0x65): undefined reference to `__real_stat'
collect2: ld returned 1 exit status
$
It seems like the error was caused due to cmake issues. Clearing the cmake cache and running cmake . followed by make all resolved it.

Declaration of unrelated char array needed to avoid program from freezing

I'm quite new to C and run into strange problem that I can not explain or solve.
#include <netinet/in.h>
#include <stdio.h>
#include <sys/socket.h>
#include <unistd.h>
void main ()
{
int sock = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in sock_addr;
sock_addr.sin_family = AF_INET;
sock_addr.sin_port = htons(1500);
connect(sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr));
puts("A");
char foo[9];
puts("B");
close(sock);
}
Code above prints out following lines:
A
B
If I comment out char foo[9] or change 9 to some smaller value then nothing is being printed out and program hangs. Looks like connect is that makes program to freeze but I don't see anything wrong on that line.
How to fix above code so that char foo[9] can be removed and program still prints out A and B and then exits? Why completely unrelated char foo[9] avoids program to freeze?
I'm using GCC 6.3.0 on Ubuntu.
Converting comments to an answer.
The code shown has an incorrect return type for the main() function on Linux. That is required to be int on all systems except Windows — only on Windows can you possibly hope to use void main(). See What should main() return in C and C++ for more information.
#include <netinet/in.h>
#include <stdio.h>
#include <sys/socket.h>
#include <unistd.h>
int main(void)
{
int sock = socket(AF_INET, SOCK_STREAM, 0);
// missed error check - probably not critical
struct sockaddr_in sock_addr;
sock_addr.sin_family = AF_INET;
sock_addr.sin_port = htons(1500);
// missed intialization of sock_addr.sin_addr - crucial!
// omitted trace printing before the call
connect(sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr));
// missed error check — possibly critical
// omitted trace printing after the call - not crucial because of puts() calls
puts("A");
char foo[9];
puts("B");
close(sock);
}
Have you tried error checking the system calls? You set the port and family but not the IP address when you try to connect — that is dubious at best, erroneous at worst. I'm not immediately sure why it causes the symptoms you're seeing, but there are problems en route to where the trouble occurs. It could be that your changed code changes the IP address part of sock_addr and your system is hanging trying to contact an uncontactable machine.
How long have you waited before deciding the program's frozen?
Have you tried adding fprintf(stderr, "BC\n"); before the call to connect() and fprintf(stderr, "AC\n"); after it? Does the call hang?
Are you using the optimizer at all?
Do you compile with warnings enabled, such as warnings for unused variables? (Use gcc -Wall -Werror -Wextra -Wstrict-prototypes -Wmissing-prototypes as a starting point — if it doesn't compile cleanly under those options, it quite possibly won't run cleanly either. Include -g for debug information and -O3; if you're doing serious debugging in a debugger, then drop the -O3.)
The code doesn't initialize the sock_addr variable properly — it doesn't set the sin_addr at all, so you're connecting to an indeterminate IP address (you've literally no idea what you're trying to connect to). At minimum, use struct sockaddr_in sock_addr = { 0 }; to set it to zeros. Or use memset(&sock_addr, '\0', sizeof(sock_addr));. You're invoking undefined behaviour because you don't initialize the structure properly. And variable responses from compilers and optimizers is symptomatic of undefined behaviour.
Karmo Rosental notes:
It is connecting to localhost when it's not freezing but your suggestion struct sockaddr_in sock_addr = { 0 }; helped to avoid freezing in GCC.

problems compiling c code with libusb on linux

I'm trying to use libusb for a project but i'm unable to get the library working properly. Here is some source code i'm trying to compile. It doesn't do anything special. It's just a dummy program that gets the USB driver list then frees it.
#include <stdio.h>
#include <usb.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
struct libusb_device **devs;
struct libusb_context *context = NULL;
size_t list;
size_t i;
int ret;
ret = libusb_init(&context);
if(ret < 0)
{
perror("libusb_init");
exit(1);
}
list = libusb_get_device_list(context, &devs);
if(list < 0)
{
fprintf(stderr, "error in getting device list\n");
libusb_free_device_list(devs, 1);
libusb_exit(context);
exit(1);
}
libusb_free_device_list(devs, 1);
libusb_exit(context);
return 0;
}
I compile with
gcc -o test test.c -lusb
I get the error
/tmp/cc2hwzii.o: in function 'main:
test.c:(.text+0x24): undefined reference to 'libusb_init'
test.c:(.text+0x59): undefined reference to 'libusb_get_device_list'
test.c:(.text+0x8e): undefined reference to 'libusb_free_device_list'
test.c:(.text+0x9f): undefined reference to 'libusb_exit'
collect2: error: ld returned 1 exit status
I'm running ubuntu 14.04.3
I've installed libusb by sudo apt-get install libusb-dev
I've searched for my header file and it is called usb.h
I've looked to make sure I have the correct flag and it's -lusb
any ideas? I'd appreciate the help. If any more information is needed just ask.
those libusb_init are included in libusb-1.0.
you have to install libusb-1.0-0-dev
$ sudo apt-get install libusb-1.0-0-dev
$ gcc -o test test.c -lusb-1.0
/usr/lib/x86_64-linux-gnu/pkgconfig/libusb.pc which is included in libusb-dev says that the version is 0.1.12
and
/usr/lib/x86_64-linux-gnu/pkgconfig/libusb-1.0.pc which is included in libusb-1.0-0-dev says that the version is 1.0.17.
http://www.libusb.org/ says that 0.1 is legacy, and seems that API is different from 1.0.
You forgot to include the file that defines the functions, such as libusb_init. Have you tried including libusb.h?

Compile Attempt Gives crt1.o/'start'/undefined reference to 'main'/exit status message

I am working from a book: TCP/IP Sockets in C and its website code.
I am trying to build a client and server based on those files. My make gives lots of
error related to not being able to find functions from DieWithMessage.c
Here it is:
#include <stdio.h>
#include <stdlib.h>
#include "Practical.h"
void DieWithUserMessage(const char *msg, const char *detail) {
fputs(msg, stderr);
fputs(": ", stderr);
fputs(detail, stderr);
fputc('\n', stderr);
exit(1);
}
void DieWithSystemMessage(const char *msg) {
perror(msg);
exit(1);
}
When I do gcc DieWithMessage.c, I get the following error:
/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/../../../crt1.o: In function _start':
(.text+0x18): undefined reference tomain'
collect2: ld returned 1 exit status
How do I compile this by itself so that the errors will stop happening when using the makefile?
Thanks for any help.
Your C code needs a main function if you're going to try an link/run it. This is a requirement for hosted C applications under the standard.
That error message indicates what's wrong. The C runtime/startup code (CRT) has an entry point of start which sets up the environment then calls your main. Since you haven't provided a main, it complains.
If you only want to generate an object file for later linking with a main (see here for one description of the process), use something like:
gcc -c -o DieWithMessage.o DieWithMessage.c
(-c is the "compile but don't link" flag). You can then link it later with your main program with something like (although there are other options):
gcc -o myProg myProg.c DieWithMessage.o
If you want a placeholder main to update later with a real one, you can add the following to your code:
int main (void) { return 0; }

Resources