Hey,
I'm trying to send a HTTP request using Winsock and I'm getting a rather beautiful linker error stating the following:
My code is here:
Main CPP File
Connector.h
Connector.cpp
Things I've Tried:
It's limited seeing as I have little to no clue what is going on. I did try to comment out the code in the sendRequest() function and this did not work. However, commenting out the calling of that function in Main.cpp makes the error go away.
I had the same problem before with the init() method in Connector.cpp, but not with connect() in the same file...
From what I understand, the error is caused by a library not being linked correctly. However, my code is strongly based on this MSDN tutorial and I have added the three #pragma statements I need in Connector.h.
Any help is appreciated, so thanks to anyone who looks over this!
Cbeppe.
I'm trying to send a HTTP request using Winsock and I'm getting a rather beautiful linker error stating the following:
Quote
error LNK2019: unresolved external symbol "public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall Connector::sendRequest(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?sendRequest@Connector@@QAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V23@0@Z) referenced in function _main
1>C:\Users\...\Main.exe : fatal error LNK1120: 1 unresolved externals
1>C:\Users\...\Main.exe : fatal error LNK1120: 1 unresolved externals
My code is here:
Main CPP File
// MAIN.CPP #include "stdio.h" #include "Connector.h" using namespace std; int main() { Connector conn; string request; string response; request+= "GET / HTTP/1.0\r\n"; request+= "Host: www.google.com\r\n"; request+= "\r\n"; conn.init(); response = conn.sendRequest("74.125.228.38",request); printf(response.c_str()); system("PAUSE"); }
Connector.h
//Connector.h #ifndef connector_H #define connector_H #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif #include <windows.h> #include <winsock2.h> #include <ws2tcpip.h> #include <iphlpapi.h> #include <string> #pragma comment (lib, "Ws2_32.lib") #pragma comment (lib, "Mswsock.lib") #pragma comment (lib, "AdvApi32.lib") using namespace std; class Connector { public: void init(); SOCKET connect(string address); string sendRequest(string address, string request); private: int iResult; }; #endif
Connector.cpp
#include "Connector.h" #include "stdio.h" #include <string> #define DEFAULT_BUFLEN 512 #define DEFAULT_PORT "80" using namespace std; int iResult; void Connector::init() { WSADATA wsaData; iResult = WSAStartup(MAKEWORD(2,2), &wsaData); if (iResult != 0) { printf("WSAStartup failed: %d\n", iResult); return; } return; } SOCKET connect(string address) { struct addrinfo *result = NULL, *ptr = NULL, hints; SOCKET ConnectSocket = INVALID_SOCKET; ZeroMemory(&hints, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; // Resolve server address and port iResult = getaddrinfo(address.c_str(), DEFAULT_PORT, &hints, &result); if (iResult != 0) { printf("getaddrinfo failed with error: %d\n", iResult); WSACleanup(); return INVALID_SOCKET; } // connect to address for (ptr=result; ptr != NULL; ptr=ptr->ai_next) { // Create socket for connecting to server ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); if (ConnectSocket == INVALID_SOCKET) { printf("socket failed with error: %ld\n", WSAGetLastError()); WSACleanup(); return INVALID_SOCKET; } // Connect to Server iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen); if (iResult == SOCKET_ERROR) { closesocket(ConnectSocket); ConnectSocket = INVALID_SOCKET; continue; } break; } freeaddrinfo(result); if (ConnectSocket == INVALID_SOCKET) { printf("Unable to connect to server!\n");; WSACleanup(); return INVALID_SOCKET; } return ConnectSocket; } string sendRequest(string address, string request) { SOCKET sock = connect(address); string response = ""; int recvbuflen = DEFAULT_BUFLEN; char recvbuf[DEFAULT_BUFLEN]; // Exit the function if the socket failed to connect if (sock == INVALID_SOCKET) return "ERROR: COULD NOT CONNECT SOCKET"; // Send a request to the server; Print error if relevant. iResult = send(sock, request.c_str(), request.length(), 0); if (iResult == SOCKET_ERROR) { printf("send failed: %d\n", WSAGetLastError()); closesocket(sock); WSACleanup(); return "ERROR: COULD NOT SEND REQUEST"; } // Shut down the send element of the socket. We can still receive. iResult = shutdown(sock, SD_SEND); if (iResult == SOCKET_ERROR) { printf("shutdown failed: %d\n", WSAGetLastError()); closesocket(sock); WSACleanup(); return "ERROR: COULD NOT SHUT DOWN SOCKET"; } // Receive response from server do { iResult = recv(sock, recvbuf, recvbuflen, 0); if (iResult > 0) response+= string(recvbuf).substr(0,recvbuflen); else if (iResult == 0) printf("Connection closed\n"); else printf("recv failed: %d\n", WSAGetLastError()); } while (iResult > 0); // Cleanup closesocket(sock); WSACleanup(); return response; }
Things I've Tried:
It's limited seeing as I have little to no clue what is going on. I did try to comment out the code in the sendRequest() function and this did not work. However, commenting out the calling of that function in Main.cpp makes the error go away.
I had the same problem before with the init() method in Connector.cpp, but not with connect() in the same file...
From what I understand, the error is caused by a library not being linked correctly. However, my code is strongly based on this MSDN tutorial and I have added the three #pragma statements I need in Connector.h.
Any help is appreciated, so thanks to anyone who looks over this!
Cbeppe.