C++ Custom Client Handler - c++

Below is the code that accepts a client... I just added a bit to add it to a pool which is a list<Client>. Client is my own class that is defined by (SOCKET, Char*) socket and ip address. The addclient2pool() function just adds to the list. Then I iterate through the list and send data via the stored socket in Client.
while(true) {
ClientSocket = accept(ListenSocket, (struct sockaddr *) &n, &len);
if (ClientSocket == INVALID_SOCKET) {
printf("accept failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return;
}
addClient2Pool(Client(ListenSocket, inet_ntoa(n.sin_addr)));
}
The socket seems to have closed so I can't send messages... 10057. I am pretty sure there's something fundamentally wrong with the way I am storing the socket into Client class but I am new to C++.
void messageHandler() {
int iSend;
char* charB = "hello!";
while(true) {
for(ClientPool::iterator it = mainClientPool.begin(); it != mainClientPool.end(); ++it) {
Client c = *it;
SOCKET sock = c.getSocket();
iSend = send(sock, charB, sizeof(charB),0);
if (iSend == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
}
}
Sleep(2000);
}
}
I used std::thread nameofthread(void) and nameofthread.join();

I see several issues with your code.
You are passing ListenSocket to Client() when you should be passing ClientSocket instead:
addClient2Pool(Client(ClientSocket, inet_ntoa(n.sin_addr)));
If you need to shut down the server for any reason, you should close any active client sockets first. In your example, if accept() fails, you are calling closesocket(ListenSocket) and WSACleanup() without clearing mainClientPool first (I assume your ~Client() deconstructor calls closesocket() on the client socket):
mainClientPool.clear(); // <-- add this
closesocket(ListenSocket);
WSACleanup();
When looping through your list, you need to use a Client& reference when deferencing the iterator so you are not making temporary copies of your Client objects that invoke their destructors when they go out of scope (thus closing your client sockets):
Client &c = *it; // <-- add '&'
You are misusing sizeof(). Since charB is a char* and not a char[], you need to use strlen() instead:
iSend = send(sock, charB, strlen(charB), 0);
Lastly, when send() (or any other socket operation) fails, you should close the failed client socket and remove it from your list. Which means changing your for() loop into a while() loop so you can modify the list while you are looping through it:
void messageHandler() {
...
while(true) {
...
ClientPool::iterator it = mainClientPool.begin();
while (it != mainClientPool.end()) {
...
if (iSend == SOCKET_ERROR) {
...
it = mainClientPool.erase(it);
} else {
++it;
}
}
...
}
...
}

Related

Why isn't AF_INET working with SOCK_STREAM?

I'm just starting out on gaining a better understanding of socket programming, and I'm trying to build a simple program that can send and receive messages. I've run into an issue with binding a socket to an address to use it. Here is what I have-
#include "stdafx.h"
using namespace std;
int main()
{
bool devbuild = true;
WSADATA mainSdata;
SOCKET sock = INVALID_SOCKET;
sockaddr tobind;
tobind.sa_family = AF_INET;
char stringaddr[] = "192.168.1.1";
inet_pton(AF_INET,stringaddr,&tobind);
//initiating Windows Socket API (WSA)
if (WSAStartup(2.2, &mainSdata) == 0)
{
if (devbuild == true)
{
printf("WSA successfully started...\n");
}
}
else
{
printf("WSA failed to set up, press [ENTER] to exit...\n");
pause();
return 1;
}
//instantiating the socket
sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, NULL);
if (sock != INVALID_SOCKET)
{
if (devbuild == true)
{
printf("Socket successfully created...\n");
}
}
else
{
printf("Socket failed to set up, press [ENTER] to exit...\n");
pause();
return 2;
}
//binding the socket
if (bind(sock, &tobind, sizeof(tobind)) == 0)
{
if (devbuild == true)
{
printf("Socket successfully bound...\n");
}
}
else
{
printf("Socket failed to bind, press [ENTER] to exit...\n");
printf("Last WSA error was: %d", WSAGetLastError());
pause();
return 3;
}
pause();
return 0;
}
I'm getting a return of 3, with WSA error code 10047
10047 - WSAEAFNOSUPPORT
Address family not supported by protocol family.
An address incompatible with the requested protocol was used. All sockets are created with an associated address family (that is, AF_INET for Internet Protocols) and a generic protocol type (that is, SOCK_STREAM). This error is returned if an incorrect protocol is explicitly requested in the socket call, or if an address of the wrong family is used for a socket, for example, in sendto.
This doesn't make sense, because I am only using SOCK_STREAM and AF_INET, which support one another.
I believe one problem (possibly not the only problem, but this is what jumps out at me) is in this line:
inet_pton(AF_INET,stringaddr,&tobind);
The problem is that you are passing &tobind as the final argument, and tobind is a sockaddr, but inet_pton() expects its third argument to point to a struct in_addr instead when using AF_INET (the fact that inet_pton() takes a void-pointer rather than a typed pointer for its third argument makes this kind of mistake really easy to make).
So what you should be doing instead is (note added error checking also):
if (inet_pton(AF_INET,stringaddr,&tobind.sin_addr) != 1)
printf("inet_pton() failed!\n");
Also, you need to make tobind be of type struct sockaddr_in rather than just a sockaddr, and also you need to zero out the struct before using it:
struct sockaddr_in tobind;
memset(&tobind, 0, sizeof(tobind)); // make sure the uninitialized fields are all zero
tobind.sa_family = AF_INET;
[...]

make the connaction to IPv6 or IPv4 easy?

I am create socket class but I want to make my Connect function dynamic and can connect to address(ipv4 or ipv6) use switch to make IPv test and connect to supported IPv just wan to ask if I am right or is there an easy way to make it to make IPv4 or IPv6?
bool Connect(short port,std::string addr,bool vlisten,HWND WindowHandle,WSADATA& wsaData,bool async)
{
if(!hSocket);
{
this->port = port;
this->addr =addr;
this->vlisten = vlisten;
this->WindowHandle = WindowHandle;
this->wsaData =wsaData;
this->init = true;
// Provide big enough buffer, ipv6 should be the biggest
char ipstr[INET6_ADDRSTRLEN];
char ipstr2[INET6_ADDRSTRLEN];
struct sockaddr_in* sockaddr_ipv4;
struct sockaddr_in6* sockaddr_ipv6;
//struct sockaddr_in6* sockaddr_ipv6;
if(WSAStartup(MAKEWORD(2,2),&wsaData) !=0)
{
throw runtime_error("Error WSAStartup:" + WSAGetLastError());
}
if((this->hSocket = ::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))== INVALID_SOCKET)
{
Close();
throw runtime_error("Error init sockect:" + WSAGetLastError());
}
if(addr != "INADDR_ANY")
{
struct addrinfo *result = nullptr;
getaddrinfo(addr.c_str(), nullptr, nullptr, &result);
struct addrinfo *it;
for (it = result; it != nullptr; it = it->ai_next)
{
//sockaddr_ipv4 = reinterpret_cast<sockaddr_in*>(it->ai_addr);
//addr = inet_ntoa(sockaddr_ipv4->sin_addr);
//if (addr != "0.0.0.0") break;
switch (it->ai_family)
{
case AF_UNSPEC:
cout<<"Unspecified\n"<<endl;
break;
case AF_INET:
cout<<"AF_INET (IPv4)\n"<<endl;
sockaddr_ipv4 = reinterpret_cast<sockaddr_in*>(it->ai_addr);
//printf("\tIPv4 address %s\n",
addr = inet_ntoa(sockaddr_ipv4->sin_addr);
/*if (addr != "0.0.0.0") break;*/
break;
case AF_INET6:
cout<<"AF_INET (IPv6)\n"<<endl;
sockaddr_ipv6 = reinterpret_cast<sockaddr_in6*>(it->ai_addr);
addr = inet_ntop(it->ai_family,sockaddr_ipv6,(PSTR)ipstr,sizeof(ipstr));
break;
case AF_NETBIOS:
cout<<"AF_NETBIOS (NetBIOS)\n"<<endl;
break;
default:
printf("Other %ld\n", it->ai_family);
break;
}
}
freeaddrinfo(result);
}
}
SOCKADDR_IN sockAddrIn;
memset(&sockAddrIn,0,sizeof(sockAddrIn));
sockAddrIn.sin_port = htons(port);
sockAddrIn.sin_family = AF_INET;
sockAddrIn.sin_addr.s_addr = (addr == "INADDR_ANY" ? htonl(INADDR_ANY) : inet_addr(addr.c_str()));
if(vlisten && (bind(hSocket,reinterpret_cast<SOCKADDR*>(&sockAddrIn),sizeof(sockAddrIn))== SOCKET_ERROR))
{
Close();
throw runtime_error("Error vlisten & bind: " + WSAGetLastError());
}
if(async && WindowHandle)
{
if(WSAAsyncSelect(hSocket,WindowHandle,WM_SOCKET,FD_READ|FD_WRITE|FD_CONNECT|FD_CLOSE|FD_ACCEPT) !=0)
{
Close();
throw runtime_error("Error async & WindowHandle: " + WSAGetLastError());
}
}
if(vlisten && (listen(hSocket,SOMAXCONN)== SOCKET_ERROR))
{
Close();
throw runtime_error("Error async & WindowHandle: " + WSAGetLastError());
}
if(!vlisten && (connect(hSocket, reinterpret_cast<SOCKADDR*>(&sockAddrIn), sizeof(sockAddrIn)) == SOCKET_ERROR))
{
if(async && WindowHandle && (WSAGetLastError() != WSAEWOULDBLOCK))
{
Close();
throw runtime_error("Error async & WindowHandle: " + WSAGetLastError());
}
}
}
Your code has multiple issues:
First, you correctly called getaddrinfo(), but then you completely threw away the results without using them.
You called listen() but you appear to intend to make an outgoing connection; listen() is meant to listen for incoming connections.
Instead of using the information from getaddrinfo() you ignore it and assume IPv4 when filling out your sockaddr_in structure. This part of the code should just be scrapped.
There's no need to explicitly check the returned address family. You won't get any address families that the computer can't handle.
You appear to be writing a single method which does more than one thing, i.e. both make outgoing connections and accept incoming connections. Methods should only do one thing.
Let's go back to the beginning and get a minimal outgoing connection up. I'm omitting anything here not directly related to creating the connection (e.g. the call to WSAAsyncSelect() and other stuff which belongs in separate methods anyway):
// Connect to a remote host, given its address and port number.
bool Connect(short port, std::string addr)
{
struct addrinfo *result, *rp;
// TODO: You passed us an integer port number. We need a C string.
// Clean up this mess.
char portstr[255];
portstr = sprintf("%d", port);
if (getaddrinfo(addr.c_str(), portstr, nullptr, &result)) {
throw runtime_error("getaddrinfo: " + WSAGetLastError());
}
// A host can have multiple addresses. Try each of them in turn until
// one succeeds. Typically this will try the IPv6 address first, if
// one exists, then the IPv4 address. The OS controls this ordering
// and you should not attempt to alter it. (RFC 6724)
for (rp = result; rp != nullptr; rp = rp->ai_next) {
this->hSocket = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
// Check socket creation failed; maybe harmless (e.g. computer
// doesn't have IPv6 connectivity). Real errors will get thrown below.
if (this->hSocket == -1)
continue;
if (connect(this->hSocket, rp->ai_addr, rp->ai_addrlen) != -1)
break; // Success
close(this->hSocket);
}
if (rp == NULL) { // No address succeeded
throw runtime_error("connect: " + WSAGetLastError());
}
freeaddrinfo(result);
// Now this->hSocket has an open socket connection. Enjoy!
}
The major thing to note is that getaddrinfo() handles all the heavy lifting for you. The structure it returns has all the information needed to create the connection; you only have to use it.
If you want the connection information, such as address and family, you can copy those out of rp and store them somewhere before it goes out of scope.
Writing the separate method to handle incoming connections is left as an exercise for the reader. Your example code appears to be partly based on the sample on the MSDN page for getaddrinfo; the Linux getaddrinfo manual page has much better examples (the sample code actually works with minimal change on Windows).

Win Socket UDP connection-less recvfrom() Error

I'm working on a legacy VC6 application, that uses winsocket to listen to a UDP port for incoming packets. However I am getting the following errors. If I use WSAGetLastError() I get WSAECONNRESET, which if I read the description, doesn't seem to make sense, because its saying that remote host forcibly closed the socket, But I want use UDP connection-less manor, so it shouldn't matter what the other machine is doing... we should just listen. If I check the errno and use sterror() I get the following message. "No such file or directory". (I think this it's enum is EIO, according to http://pubs.opengroup.org/onlinepubs/009695399/functions/recvfrom.html)
I've had some success in narrowing down the issue, it appears if I take out a sendto() call, that calls back on the same port as the recvfrom(), the code seems to work ok. So something with that sendto() is putting in a bad state.
I'm looking for suggestions on why this socket is going bad, and either how to prevent or recover.
Edit
Here is the other weird part, if do the setup again for that socket (after a recvfrom() fails)... it all seems to work, even additional calls to sendto() don't seem trigger a recvfrom() fail, which in turn would call the setup again..
CODE
static VOID SetupSocketAddress( SOCKADDR_U &saRx, int nRTDPort )
{
memset(&saRx.saIPX, 0, sizeof(SOCKADDR_IPX));
saRx.saIPX.sa_family = AF_IPX; // IPX type address
memset(saRx.saIPX.sa_netnum,0x00,4); // we may have to get this number
memset(saRx.saIPX.sa_nodenum,0xff,6); // broadcast address
saRx.saIPX.sa_socket=(unsigned short)nRTDPort; // socket number
}
void CRealTimeData::SetupSocket( CRealTimeData * lpRTD, BOOL &bDone, SOCKADDR_U &saRx, int nRTDPort, SOCKADDR_U &saFrom, int &cbAddr,
DWORD &dwLocalAddress, int &nMaxIpIpxBuf, char * &pbyIpIpxRxBuf, int nFlags, BOOL bDo)
{
char szErrorCode[32];
int nReturn = 0;
if (lpRTD->m_eSourceType == V7_RTD_IPX)
{
// open IPX socket
// packet type = 4
lpRTD->m_Socket=socket(AF_IPX, SOCK_DGRAM, NSPROTO_IPX+4);
if (lpRTD->m_Socket == INVALID_SOCKET)
{
nReturn = AddSocketErrorToEventViewer( lpRTD);
bDone = TRUE;
}
// Socket must be bound prior to calling recvfrom()
// setup address
SetupSocketAddress(saRx, nRTDPort);
#ifdef _DEBUG_IPX
// test changing host number to network number
// we can't actually change though, because other programs use it this way
u_short nNetPort=0;
int nRet=WSAHtons(lpRTD->m_Socket, (unsigned short)nRTDPort, &nNetPort);
TRACE(_T("RTDIpxThread: Host Port=%04x Net Port=%04x RTD Input=%d \n"),nRTDPort, nNetPort, lpRTD->GetInputNumber());
#endif
// setup address for Sending Data on RTD
SetupSocketAddress( lpRTD->m_saRTD, nRTDPort );
// copy address - Why are we copying the address just over right later (in recvfrom() )? -NG
memcpy(&saFrom.saIPX, &lpRTD->m_saRTD.saIPX, sizeof(SOCKADDR_IPX));
cbAddr = sizeof(SOCKADDR_IPX);
}
else
{
// open IP socket
lpRTD->m_Socket=socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); // ??? should this use IPPROTO_UDP???
if (lpRTD->m_Socket == INVALID_SOCKET)
{
nReturn = AddSocketErrorToEventViewer( lpRTD);
bDone = TRUE;
}
// Socket must be bound prior to calling recvfrom()
// setup address
memset(&saRx.saIP, 0, sizeof(SOCKADDR_IN));
saRx.saIP.sin_family = AF_INET; // IP type address
saRx.saIP.sin_port=htons((u_short)nRTDPort); // PORT number
saRx.saIP.sin_addr.s_addr=htonl(INADDR_ANY); // ADDRESS number
// setup for Sending Data on RTD port
memset(&lpRTD->m_saRTD.saIP, 0, sizeof(SOCKADDR_IN));
lpRTD->m_saRTD.saIP.sin_family = AF_INET; // IP type address
lpRTD->m_saRTD.saIP.sin_port=htons((u_short)nRTDPort); // PORT number
lpRTD->m_saRTD.saIP.sin_addr.s_addr=htonl(INADDR_BROADCAST); // ADDRESS number
// copy address - Why are we copying the address just over right later (in recvfrom() )? -NG
memcpy(&saFrom.saIP, &lpRTD->m_saRTD.saIP, sizeof(SOCKADDR_IN));
cbAddr = sizeof(SOCKADDR_IN);
char szHostName[MAX_PATH+1];
if (gethostname(szHostName, MAX_PATH)==0)
{
hostent *phe=gethostbyname(szHostName);
dwLocalAddress = *(DWORD*)&phe->h_addr_list[0];
}
} // end IP socket
if (!bDone)
{
// enable broadcasting
BOOL bOptVal=TRUE;
nReturn=setsockopt(lpRTD->m_Socket, SOL_SOCKET, SO_BROADCAST, (char *)&bOptVal, sizeof(BOOL));
if (nReturn == SOCKET_ERROR)
{
nReturn=WSAGetLastError();
}
// enable reuse of address
bOptVal=TRUE;
nReturn=setsockopt(lpRTD->m_Socket, SOL_SOCKET, SO_REUSEADDR, (char *)&bOptVal, sizeof(BOOL));
if (nReturn == SOCKET_ERROR)
{
nReturn=WSAGetLastError();
}
// get the socket's max message size
int nOptSize=sizeof(UINT);
UINT nMaxMsgSize=600;
nReturn=getsockopt(lpRTD->m_Socket, SOL_SOCKET, SO_MAX_MSG_SIZE, (char *)&nMaxMsgSize, &nOptSize);
if (nReturn == SOCKET_ERROR)
{
nReturn=WSAGetLastError();
nMaxMsgSize=600; // default max size
}
nMaxIpIpxBuf=nMaxMsgSize; // always create buffer that is as big as the sockets max message size
pbyIpIpxRxBuf = new char[nMaxIpIpxBuf]; // allocate buffer for receiving data from socket
if (!pbyIpIpxRxBuf)
bDone = TRUE;
else
memset(pbyIpIpxRxBuf,0,nMaxIpIpxBuf*sizeof(char));
// bind to address
nReturn=bind(lpRTD->m_Socket, &saRx.sa, cbAddr);
if (nReturn == SOCKET_ERROR)
{
nReturn = AddSocketErrorToEventViewer(lpRTD);
bDone = TRUE;
}
// send data to indicate startup
if (lpRTD->m_eProtocol == V7_RTD_ENHANCED)
{
int nLen=lpRTD->BuildErrorMsg(V7_ERTD_SERVICE_STARTUP, szErrorCode, sizeof(szErrorCode));
nReturn=sendto(lpRTD->m_Socket,szErrorCode,nLen, nFlags, &lpRTD->m_saRTD.sa, cbAddr);
if (nReturn == SOCKET_ERROR)
{
nReturn=WSAGetLastError();
}
}
} // end if not done
}
Main()
nFromLen = cbAddr;
nReturn=recvfrom(lpRTD->m_Socket, pbyIpIpxRxBuf, nMaxIpIpxBuf, nFlags, &saFrom.sa, &nFromLen);
if(nReturn == SOCKET_ERROR)
{
SetupSocket(lpRTD, bDone, saRx, nRTDPort, saFrom, cbAddr, dwLocalAddress, nMaxIpIpxBuf, pbyIpIpxRxBuf,nFlags, FALSE);
nReturn=recvfrom(lpRTD->m_Socket, pbyIpIpxRxBuf, nMaxIpIpxBuf, nFlags, &saFrom.sa, &nFromLen);
}
// if i take this out no error....
nReturn=sendto(lpRTD->m_Socket, szErrorCode, nLen, nFlags, &saFrom.sa, cbAddr);

C++ - client-server application - recv() on server is functional, but recv() on client blocks program

I'm writing client-server application. Until now everything was OK, client sent a request, server recieved it, parse it. But now I want to send back an answer, so I copied those two functions, I put write() from client to server and read() from server to client. And when I run the program now everything blocks, server waits, client waits too. When I ctrl+c client, server unblocks and parse the right request and waits for another. What could be wrong, please?
Part of code from client:
params.port = atoi(params.pvalue.c_str());
hostent *host;
sockaddr_in socketHelper;
int clientSocket;
char buf[BUFFER_LEN];
int size;
string data;
string recieved;
// gets info about server
host = gethostbyname(params.hvalue.c_str());
if(host == NULL) {
printErr(ERR_HOSTNAME);
return ERR_HOSTNAME;
}
// makes a socket
if((clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
printErr(ERR_SOCKET);
return ERR_SOCKET;
}
socketHelper.sin_family = AF_INET;
socketHelper.sin_port = htons(params.port);
memcpy(&(socketHelper.sin_addr), host->h_addr, host->h_length);
// connects the socket
if(connect(clientSocket, (sockaddr *)&socketHelper, sizeof(socketHelper)) == -1) {
printErr(ERR_CONNECTION);
return ERR_CONNECTION;
}
// sends data
if((size = write(clientSocket, request.c_str(), request.length())) == -1) {
printErr(ERR_SEND);
return ERR_SEND;
}
// recieves data
while ((size = read(clientSocket, buf, BUFFER_LEN)) != 0) {
recieved.erase();
recieved.append(buf, size);
data = data + recieved;
}
// closes a connection
close(clientSocket);
And part of code from server:
while(1) {
int clientSocket = accept(GodParticle, (struct sockaddr*) &GodAddr, &clientSocketSize);
if(clientSocket == -1) {
printErr(ERR_ACCEPT);
return ERR_ACCEPT;
}
if((pid = fork()) == 0) {
while ((size = read(clientSocket, buf, BUFFER_LEN)) != 0) {
recieved.erase();
recieved.append(buf, size);
request = request + recieved;
}
parserInput(request);
getData();
parserOutput();
if((size = write(clientSocket, sendback.c_str(), sendback.length())) == -1) {
printErr(ERR_SEND);
return ERR_SEND;
}
close(clientSocket);
exit(ERR_OK);
}
}
Ok, let me answer in this way.
recv() is blocking your program by default until it receive some message from server.
And the reason why recv() does not blocks your server program is because you used fork() to create a child process.
So you have to use some other method to avoid this block(maybe like using select or some other things).

bind: Socket operation on non-socket

I writing a server and a client and keep getting 'bind: Socket operation on non-socket'.
I've researched the heck out of this, have other code that runs in another application and have exhausted 8 hours trying to find this bug.
The code is:
void TCPSocket::buildTCPSocket(int port)
{
initializeSocket1();
getSocket();
bindSocket();
listenToSocket();
acceptSocket();
// now you can send() and recv() with the
// connected client via socket connectedTCPSocket
}
void TCPSocket::getSocket()
{
// Get an internet domain socket AF_INET
if(socket1 = socket(AF_INET, SOCK_STREAM,0) == -1)
{
perror("socket");
exit(1);
}
}
void TCPSocket::bindSocket()
{
// Bind to a port on the host
int myAddressSize = sizeof(myAddress);
int bindReturnValue = bind(socket1, (struct sockaddr *) &myAddress, AddressSize);
if (bindReturnValue == -1)
{
perror("bind"); // <== Error message generated here
exit(1);
}
printf("Socket for TCP bound to port %d\n", port);
}
Also, prior to this, I memset the memory block with this function.
void TCPSocket::initializeSocket1()
{
// Fill tcpSocket struct with 0's
memset(&myAddress, '\0', sizeof(myAddress));
myAddress.sin_family = AF_INET;
myAddress.sin_addr.s_addr = INADDR_ANY;
// Conver PORT to big-endian if necessary
myAddress.sin_port = htons(this->port);
}
Variables are declared in the header file of the class.
public:
struct sockaddr_in myAddress, clientAddress;
void buildTCPSocket(int newPort);
private:
int port;
int socket1, socket2;
socklen_t clientAddressLength;
-- Edit the code should be a little more clear now. socket1 is initialized in getSocket().
I've seen where a bunch of guys have missed the parens in the if but I think I eliminated that error by declaring myAddressSize and bindReturnValue.
Any input is appreciated.
Thank you,
Ted S
Ok, problem solved. Of course the problem is never where you are looking are you would have found it. Here is the corrected code. The problem was in a missing set of parens in the call to socket().
void TCPSocket::getSocket()
{
// Get an internet domain socket AF_INET
if((socket1 = socket(AF_INET, SOCK_STREAM,0)) == -1)
{
perror("socket");
exit(1);
}
}
Thanks again!
I can almost guarantee you that you're getting that error because you never initialized socket1.
Typically you have to do something like this:
int socket1 = socket(AF_INET, SOCK_STREAM, 0);
bind(socket1, ...);
I don't see any code anywhere in there for setting up socket1. This is what the error message is telling you, after all. socket1 isn't a socket, so it's failing.
Edit: As a follow up, this is one of the reasons why I try to avoid using the syntax
if ((foo = bar()) == ERROR)
{
// handle me
}
And instead stick with:
void TCPSocket::getSocket()
{
// Get an internet domain socket AF_INET
socket1 = socket(AF_INET, SOCK_STREAM, 0);
if (socket == -1)
{
perror("socket");
exit(1);
}
}