#ifndef _ClientSocket_H_
#define _ClientSocket_H_
#include "Includes.h"
#include "LOGMSGs.h"
class cSocket
{
public:
cSocket();
bool Open();
bool Listen(char *OnIP,int OnPort);
void Send(char *MSG, int len);
void Recv(char *MSG,int len);
void Close();
protected:
SOCKET cSock;
const int SndBuf;
};
#endif
#include "ClientSocket.h"
bool cSocket::Open()
{
WSADATA wsaData;
int err;
if((err =WSAStartup(0x202, &wsaData)) !=0)
{
Error("Init WSAStartup() failed[%d].", err);
return false;
}
return true;
}
bool cSocket::Listen(char *OnIP,int OnPort)
{
if(Open())
{
//Create the main socket
cSock=socket(AF_INET, SOCK_STREAM, 0);
if(cSock==INVALID_SOCKET)
{
int err = WSAGetLastError();
//WSACleanup();
printf("Init socket() failed[%d].", err);
return FALSE;
}
//Set the REUSEADDR SOCKET
int optval = 1;
if(setsockopt(cSock, SOL_SOCKET, SO_REUSEADDR, (char *) &optval, sizeof(optval)))
{
int err = WSAGetLastError();
Close();
printf("Init setsockopt() SO_REUSEADDR failed[%d].", err);
return FALSE;
}
//Set the KEEPALIVE SOCKET
optval = 1;
if(setsockopt(cSock, SOL_SOCKET, SO_KEEPALIVE, (char *) &optval, sizeof(optval)))
{
int err = WSAGetLastError();
Close();
printf("Init setsockopt() SO_KEEPALIVE failed[%d].", err);
return FALSE;
}
// Set the SNDBUF SOCKET
if(SndBuf) // Non-0: pointer SNDBUG
{
optval = SndBuf;
if(setsockopt(cSock, SOL_SOCKET, SO_SNDBUF, (char *) &optval, sizeof(optval)))
{
int err = WSAGetLastError();
Close();
printf("Init setsockopt() SO_SNDBUF failed[%d].", err);
return FALSE;
}
// Read the SNDBUF SOCKET
int ret = sizeof(optval);
if(getsockopt(cSock, SOL_SOCKET, SO_SNDBUF, (char *) &optval, &ret) == 0)
{
LOGMSG("send buffer size SOCKET [%d] K.", optval/1024);
}
}
SOCKADDR_IN sin;
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = inet_addr(OnIP);
sin.sin_port = htons(OnPort);
if(bind(cSock, (LPSOCKADDR) &sin, sizeof(sin)))
{
int err = WSAGetLastError();
Close();
printf("Init bind() failed[%d].", err);
return FALSE;
}
//Set to non-blocking mode
unsigned long i = 1;
if(ioctlsocket(cSock, FIONBIO, &i))
{
int err = WSAGetLastError();
Close();
printf("Init ioctlsocket() failed[%d].", err);
return FALSE;
}
//Listening port
if(listen(cSock, SOMAXCONN)) // SOMAXCONN: WIN macro definition
{
int err = WSAGetLastError();
Close();
printf("Init listen() failed[%d].", err);
return FALSE;
}
return true;
}
return false;
}
void cSocket::Close()
{
closesocket(cSock);
WSACleanup();
}
#include "Includes.h"
#include "LOGMSGs.h"
#include "auth_proto.h"
#include "Packets.h"
#include "ClientSocket.h"
int main(int argc, char* argv[])
{
cSocket sock;
while(1)
{
sock.Open();
sock.Listen("127.0.0.1",4444);
}
return 0;
}
错误:函数_main
中引用的未解析的外部符号“public:__thiscall cSocket :: cSocket(void)”(?? 0cSocket @@ QAE @ XZ)
出了什么问题?
答案 0 :(得分:5)
这是一个链接器错误,这意味着编译器已检查代码中是否包含语法错误,但链接器无法找到您尝试在程序中某处调用的函数的实现。在这种情况下,它找不到的功能是
__thiscall cSocket::cSocket(void)" (??0cSocket@@QAE@XZ)
由于 name-mangling ,此函数看起来很神秘,其中编译器获取函数的源代码名称,然后以允许更好的类型安全链接的方式对其进行转换。但是,您仍然可以看到在此代码中的是函数名称
cSocket::cSocket(void)
这是cSocket
的构造函数。如果您注意到,代码中没有您定义此构造函数,这就是链接器无法为其找到实现的原因。通过添加实现来修改代码应该有助于解决这个问题。
更一般地说,如果您看到这样的错误,通常意味着您已经通过函数原型或extern
声明向编译器承诺某些函数或对象存在,但是没有给出包含其定义的链接器的目标文件。造成这种情况的主要原因通常是(大致按此顺序);
void MyFunction(int)
进行原型设计,然后将该函数实现为void MyFunction(int&)
或void MyFunction()
,则链接器会认为这是一个重载而不是实现,并会给您错误在链接时而不是编译时。希望这有帮助!
答案 1 :(得分:2)
您没有声明构造函数定义
cSocket::cSocket()
{
//your init code here
}
如果您不打算使用构造函数,那么只需从类声明中删除行cSocket();