views:

149

answers:

3

I am using vc++(2010). I am trying to create a class for server side socket. Here is the header file

#include<winsock.h>
#include<string>
#include<iostream>

using namespace std;

class AcceptSocket
{
//  static SOCKET s;    
protected:

SOCKET acceptSocket;
public:
AcceptSocket(){};
void setSocket(SOCKET socket);
static void EstablishConnection(int portNo,string&);
static void closeConnection();
static void StartAccepting();
virtual void threadDeal(); 
static DWORD WINAPI MyThreadFunction(LPVOID lpParam);
};

SOCKET AcceptSocket::s;

and the corresponding source file

#include<NetWorking.h>
#include<string>

void AcceptSocket::setSocket(SOCKET s)
{
acceptSocket=s;
}

void AcceptSocket::EstablishConnection(int portno,string &failure)
{
WSAData w;
int error = WSAStartup(0x0202,&w);

if(error)
    failure=failure+"\nWSAStartupFailure";

if(w.wVersion != 0x0202)
{
    WSACleanup();
    failure=failure+"\nVersion is different";
}

SOCKADDR_IN addr;

addr.sin_family=AF_INET;

addr.sin_port=htons(portno);

addr.sin_addr.s_addr=htonl(INADDR_ANY);

AcceptSocket::s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);


if(AcceptSocket::s == INVALID_SOCKET)
    failure=failure+"\nsocket creating error";

if(bind(AcceptSocket::s,(LPSOCKADDR) &addr,sizeof(addr)) == SOCKET_ERROR)
    failure=failure+"\nbinding error";

listen(AcceptSocket::s,SOMAXCONN);

}


void AcceptSocket::closeConnection()
{
if(AcceptSocket::s)
    closesocket(AcceptSocket::s);


WSACleanup();
}

void AcceptSocket::StartAccepting()
{
sockaddr_in addrNew;
int size=sizeof(addrNew);
while(1)
{
    SOCKET temp=accept(AcceptSocket::s,(sockaddr *)&addrNew,&size);
    AcceptSocket * tempAcceptSocket=new AcceptSocket();
    tempAcceptSocket->setSocket(temp);
    DWORD threadId;
    HANDLE thread=CreateThread(NULL,0,MyThreadFunction,(LPVOID)tempAcceptSocket,0,&threadId);
}
}

DWORD WINAPI AcceptSocket::MyThreadFunction(LPVOID lpParam)
{
AcceptSocket * acceptsocket=(AcceptSocket *) lpParam;
acceptsocket->threadDeal();
return 1;
}

void AcceptSocket::threadDeal()
{
"You didn't define threadDeal in the derived class";
}

Now the main.cpp is

#include<Networking.h>

int main()
{
}

When I am compiling The error I got is

Error   1   error LNK2005: "private: static unsigned int AcceptSocket::s" (?s@AcceptSocket@@0IA) already defined in NetWorking.obj  C:\Documents and Settings\prabhakaran\Desktop\check\check\main.obj  check

Error   2   error LNK1169: one or more multiply defined symbols found   C:\Documents and Settings\prabhakaran\Desktop\check\Debug\check.exe 1   1   check

Now anybody please enlighten me about this issue

+1  A: 

Maybe a #pragma once at the very beginning of your header file will solve the problem.

The error message tells you that the linker finds multiple definitions of your class, obviously because you are including the header more than once.

That is fine in general, but then you should always add some so called inclusion guards in your header file to prevent this error.

EDIT:

Just saw that Brian R. Bondys answer is the correct one.

Frank Bollack
+3  A: 

Put this in your .cpp file instead of in your .h file:

SOCKET AcceptSocket::s;

It is being included in many .cpp files if you have it in your .h file. And hence when you link it doesn't know which one to use.

Brian R. Bondy
@Brian R.Bondy Thank you for your advice, it's working
prabhakaran
A: 

I'd like to elaborate on what Frank said. It's a common assumption that include guards might solve these kind of errors. Since the explanation got a bit lengthy, I've made a blog-post about it to explain the details: http://daniel-albuschat.blogspot.com/2010/08/what-include-guards-in-c-are-and-what.html Hope this is useful.

Daniel Albuschat