我见过很多类似的问题,但我就是不能在他们的帮助下解决这个问题。我知道这是一个链接问题,但从我所看到的情况来看,我已经理顺了链接。
我正在编写一个聊天服务器/客户端(在this article的帮助下)。
我已经定义了一个类来保存服务器函数,并有一个头文件来处理所有的包含。
这是头文件:
#include <windows.h>
#include <winsock.h>
#include <stdio.h>
#include <tchar.h>
#include <strsafe.h>
#include "resource1.h"
class ChatServer
{
public: int InitServer(HINSTANCE hInst);
public: void ReportError(int errorCode, const char *whichFunc);
};这是实际的服务器"class":
#include "server.h"
#define NETWORK_ERROR -1
#define NETWORK_OK 0
//Keeps stuff for the server
int ChatServer::InitServer(HINSTANCE hInst)
{
WORD sockVersion;
WSADATA wsaData;
int nret;
sockVersion = MAKEWORD(1,1); //Version 1.1
//Init winsock
WSAStartup(sockVersion, &wsaData);
//Create listening socket
SOCKET listeningSocket;
//AFINET - Go over TCP
//SOCK_STREAM - Stream oriented socket
//IPPROTO_TCP - Use tcp rather than udp
listeningSocket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(listeningSocket == INVALID_SOCKET)
{
nret = WSAGetLastError(); //Get error detail
ReportError(nret, "socket()");
WSACleanup();
return NETWORK_ERROR;
}
SOCKADDR_IN serverInfo;
serverInfo.sin_family = AF_INET;
serverInfo.sin_addr.s_addr = INADDR_ANY;
serverInfo.sin_port = htons(1337);
//Bind the socket to local server address.
nret = bind(listeningSocket, (LPSOCKADDR)&serverInfo, sizeof(struct sockaddr));
if(nret == SOCKET_ERROR)
{
nret = WSAGetLastError();
ReportError(nret, "bind()");
WSACleanup();
return NETWORK_ERROR;
}
//Make socket listen
nret = listen(listeningSocket, 10); //Up to 10 connections at the same time.
if(nret = SOCKET_ERROR)
{
nret = WSAGetLastError();
ReportError(nret, "listen()");
WSACleanup();
return NETWORK_ERROR;
}
//Wait for client
SOCKET theClient;
theClient = accept(listeningSocket, NULL, NULL);
if(theClient == INVALID_SOCKET)
{
nret = WSAGetLastError();
ReportError(nret, "accept()");
WSACleanup();
return NETWORK_ERROR;
}
//Send and receive from the client, and finally,
closesocket(theClient);
closesocket(listeningSocket);
//shutdown
WSACleanup();
return NETWORK_OK;
}
void ChatServer::ReportError(int errorCode, const char *whichFunc)
{
char errorMsg[92]; // Declare a buffer to hold
// the generated error message
ZeroMemory(errorMsg, 92); // Automatically NULL-terminate the string
// The following line copies the phrase, whichFunc string, and integer errorCode into the buffer
sprintf(errorMsg, "Call to %s returned error %d!", (char *)whichFunc, errorCode);
MessageBox(NULL, errorMsg, "socketIndication", MB_OK);
}最后,带有程序入口方法的main.cpp文件调用"ChatServer::InitServer(g_hInst)“。它很大,所以我省略了它,但如果需要的话,我也会把它贴出来的。
我得到的错误消息类似于下面的消息,但它们都说明了与winsockets相关的API函数的问题:
Error 3 error LNK2019: unresolved external symbol _closesocket@4 referenced in function "public: int __thiscall ChatServer::InitServer(struct HINSTANCE__ *)" (?InitServer@ChatServer@@QAEHPAUHINSTANCE__@@@Z) 正如我之前所说的,我认为这个问题与编译器误解如何处理应该链接到winsock.h的"closesocket“这样的函数有关。
感谢您的建议,并感谢您阅读所有这些胡言乱语:)
发布于 2011-08-30 00:28:56
这些链接器错误总是相同的:您使用的是链接器找不到的符号。您需要告诉链接器链接到包含这些符号的库。
正如我之前所说的,我认为这个问题与编译器误解如何处理应该链接到
的"closesocket“这样的函数有关。
不,closesocket没有链接到winsock.h。winsock.h是一个头文件,而不是一个库。它可能包含一个closesocket声明,这对于编译器来说是可以的,但是链接器确实需要知道该函数的代码在哪里,这样它才能将您的程序链接到它。
不过,您可能应该使用winsock2.h而不是winsock.h。Windows Sockets API 2.0始于1994年,版本1早已过时。
您可以在this function's documentation的底部看到它所在的库是ws2_32.lib。
发布于 2011-08-30 00:13:54
你的类可以这样定义:
class ChatServer
{
public:
int InitServer(HINSTANCE hInst);
void ReportError(int errorCode, const char *whichFunc);
};但是,您的错误是由于没有包含库输入而导致的。在项目输入行中添加对winsock库的依赖,也可以考虑使用winsock2.h。
参考:http://msdn.microsoft.com/en-us/library/ms737629(v=vs.85).aspx
发布于 2011-08-30 00:31:13
仅包含.h文件并不会导致链接实现函数的实际代码。.h文件告诉编译器这些函数存在于某个地方,以及它们的签名是什么。您仍然需要使实际实现函数的库对链接器可用。
https://stackoverflow.com/questions/7232674
复制相似问题