bind(...) always returning -1 using WinSock2 -- C++ - c++

I'm creating a game in C++ for a university project which requires some feature of networking using Sockets. My module lecturer gave us example code of working (local machine) client/servers to show us how it works. He has the following code for setting up the socket, which works fine:
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#define SERVERIP "127.0.0.1"
#define SERVERPORT 5555
void main(){
WSADATA w;
int error = WSAStartup(0x0202, &w);
if (error != 0)
{
die("WSAStartup failed");
}
if (w.wVersion != 0x0202)
{
die("Wrong WinSock version");
}
// Create a TCP socket that we'll use to listen for connections.
SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, 0);
if (serverSocket == INVALID_SOCKET)
{
die("socket failed");
}
// Fill out a sockaddr_in structure to describe the address we'll listen on.
sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr(SERVERIP);
// htons converts the port number to network byte order (big-endian).
serverAddr.sin_port = htons(SERVERPORT);
// Bind the server socket to that address.
if (bind(serverSocket, (const sockaddr *) &serverAddr, sizeof(serverAddr)) != 0)
{
die("bind failed");
}
}
However, when I replicate most of the code, bind(...) function keeps returning -1, as opposed to the 0 in my lecturers example. Here is the relevant part of my code, using classes:
TCPSocket.h
#define SERVERIP "127.0.0.1"
#define SERVERPORT 5555
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")
class TCPSocket {
public:
TCPSocket();
~TCPSocket();
void SetupServer(char* serverIP_, int serverPort_, int messageSize_);
protected:
private:
SOCKET m_socket;
sockaddr_in m_serverAddress;
char* m_serverIP;
int m_serverPort;
int m_messageSize;
};
TCPSocket.cpp
TCPSocket::TCPSocket() {
// Initialise WinSock Library, version 2.2
WSADATA w;
int error = WSAStartup(0x0202, &w);
if(error != 0) {
//error
int i = 0;
}
if(w.wVersion != 0x0202) {
//error
int i = 0;
}
}
void TCPSocket::SetupServer(char* serverIP_, int serverPort_, int messageSize_) {
m_serverIP = serverIP_;
m_serverPort = serverPort_;
m_messageSize = messageSize_;
// Create TCP socket
m_socket = socket(AF_INET, SOCK_STREAM, 0);
if(m_socket == INVALID_SOCKET) {
//error
int i = 0;
}
m_serverAddress.sin_family = AF_INET;
m_serverAddress.sin_addr.s_addr = inet_addr(SERVERIP);
m_serverAddress.sin_port = htons(SERVERPORT); // htons: port -> network byte order (big-endian)
// Bind server socket to address
int bindex = bind(m_socket, (const sockaddr *) &m_serverAddress, sizeof(m_serverAddress));
if(bindex != 0) {
//error
int a = 0;
}
}

As I said in a comment, I made a silly mistake outwith the scope of the included code: basically I was running the SetupServer() function within an update loop and the error was being caught on the second iteration of the update. Besides that, the code is perfectly functional.

Related

TCP Packet Encode/Decode

I'm learning c++ and coming from a Network Engineer background, and it is fun for me to program something that I'm familiar with it on the network side. I started creating a BGP speaker.
Here is my environment:
[mybgp]<------------TCP-Port-179------------->[bird]
Here is my current code.
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#define BIND_ADDR INADDR_ANY
#define BIND_PORT htons(179)
int createServerSocket(){
//Create Socket
int serverSocket = socket(AF_INET,SOCK_STREAM, IPPROTO_TCP);
if (serverSocket < 0) {
fprintf(stderr, "socket(): %s\n", strerror(errno));
return 1;
}
return serverSocket;
}
int createBind(const int &serverSocket, sockaddr_in &serverAddr){
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = BIND_PORT;
serverAddr.sin_addr.s_addr = INADDR_ANY;
int bind_ret = bind(serverSocket, (sockaddr *) &serverAddr, sizeof(serverAddr));
// if (bind(serverSocket, (struct sockaddr*) &serverAddr, sizeof(serverAddr)) == -1) {
// std::cerr << "Can't bind to ip/port";
// return -2;
// }
if (bind_ret < 0) {
fprintf(stderr, "bind(): %s\n", strerror(errno));
close(serverSocket);
return 1;
}
return bind_ret;
}
int createListener(const int &serverSocket){
int amount;
int listen_ret = listen(serverSocket, 3);
if (listen_ret < 0) {
fprintf(stderr, "listen(): %s\n", strerror(errno));
close(serverSocket);
return 1;
}
return listen_ret;
}
int acceptConnect(const int &serverSocket, sockaddr_in &clientAddr){
fprintf(stderr, "waiting for any client...\n");
char ip_str[INET_ADDRSTRLEN];
socklen_t caddr_len = sizeof(clientAddr);
int serverConn = accept(serverSocket, (sockaddr *) &clientAddr, &caddr_len);
if (serverConn < 0) {
fprintf(stderr, "accept(): %s\n", strerror(errno));
close(serverSocket);
close(serverConn);
return 1;
}
inet_ntop(AF_INET, &(clientAddr.sin_addr), ip_str, INET_ADDRSTRLEN);
fprintf(stderr, "accept(): new client from %s.\n", ip_str);
return serverConn;
}
int main(){
//Create Socket
int serverSocket = createServerSocket();
// declare server and client address struct
// bind socket.
sockaddr_in serverAddr, clientAddr;
memset(&serverAddr, 0, sizeof(serverAddr));
int bind_ret = createBind(serverSocket, serverAddr);
// listening for connection
int listen_ret = createListener(serverSocket);
int serverConn = acceptConnect(serverSocket, clientAddr);
// we only do one at a time, no new client.
char buffer[4048] = {0};
char valread;
valread = read( serverConn , buffer, 4048);
printf("%s\n",buffer );
close(serverSocket);
return 0;
}
My current state is that I'm able to:
Create Socket
Bind the Socket to IP
Listening
Accept a Single Connection(Single thread for now)
Received Data
At step 5, I received a gibberish TCP Message from the BGP speaker(BIRD). Knowing how the BGP Protocol works, this TCP message is in an OPEN Message Format. To establish BGP peering, mybgp and bird need to go back and for with different types of messages and agree.
For me to be able to accomplish this peering, I have to:
Decode[Received Package]
Encode[send package]
How can I decode/encode the TCP packet so I can start the process of BGP peering.

how to accept multiple clients with a simple winsock tcp server?

I can't figure out how to accept multiple connections for a simple tcp server using winsock.
I've tried a couple different ways and I can't figure out how to get another connection to work. The first call to accept() seems to be the only one that works. Can someone provide a simple example of how to do this or explain what's going on with listen() and accept() here?
#include <string>
#include <Winsock2.h>
WSADATA WsaData;
unsigned char packet_in[64];
unsigned short port = 29992;
unsigned int max_packet_size = sizeof(packet_in);
sockaddr_in xaddress;
SOCKET sock;
SOCKET sock1 = INVALID_SOCKET;
SOCKET sock2 = INVALID_SOCKET;
int main()
{
int r = WSAStartup( MAKEWORD(2,2), &WsaData );
xaddress.sin_family = AF_INET;
xaddress.sin_port = htons(port);
DWORD nonBlocking = 1;
sockaddr_in from;
int fromLength = sizeof( from );
int count = 0;
sock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
r = bind(sock, (const sockaddr*) &xaddress, sizeof(sockaddr_in));
if (r != 0) printf("%d\n", WSAGetLastError());
r = listen(sock, SOMAXCONN);
if (r == SOCKET_ERROR)
printf("%d\n",WSAGetLastError());
ioctlsocket(sock, FIONBIO, &nonBlocking);
while(true)
{
if(count == 0)
{
sock1 = accept(sock, NULL, NULL);
}
else if (count == 1)
{
sock2 = accept(sock, NULL, NULL);
}
if(sock1 != INVALID_SOCKET)
count = 1;
if(sock2 != INVALID_SOCKET)
count = 2;
printf("%i\n",count);
}
return 0;
}
I don't know how to network programming on Windows, but it basically looks like on Linux, so this is small example for Linux.
struct sockaddr_in server_addr
socklen_t len = sizeof(server_addr);
...
while(1)
{
struct sockaddr_in client_addr;
int client_fd;
if((client_fd = accept(server_sock, (struct sockaddr*)& client_addr, &len)) < 0)
{
cerr<<"accept() error"<<endl;
continue;
}
...
}
There is full example written in Polish, but you should understand:
full example (find //server.c)
Main differences between network programming on Windows and Linux are structures and classes, so it should give you some knowledge: Beej's guide to network programming
I think from this simple program, You will get better idea :)
// Multi-Client - Server chat application
#include"header.h"
void isr(int n)
{
printf("Client is Disconnected ..\n");
kill(getpid(),9);
return;
}
main()
{
int sockfd,nsfd,len,pid,size;
char buffer[500],buffer1[500];
struct sockaddr_in server;
///////////////////////////////////////////////////////////////////////
sockfd=socket(AF_INET,SOCK_STREAM,0);
if(sockfd==0)
{
printf("Socket file is not created socket is fail...\n");
return;
}
////////////////////////////////////////////////////////////////////////
server.sin_family=AF_INET;
server.sin_port=htons(9898);
len = sizeof(server);
/////////////////////////////////////////////////////////////////////
bind(sockfd,(struct sockaddr*)&server,len);
perror("bind");
/////////////////////////////////////////////////////////////
listen(sockfd,5);
perror("listen");
/////////////////////////////////////////////////////////////////
bzero(buffer,sizeof(buffer));
zero(buffer1,sizeof(buffer1));
//////////////////////////////////////////////////////////////////////
while(1)
{
nsfd=accept(sockfd,(struct sockaddr *)&server,&len);
if(nsfd<0)
{
perror("accept");
return;
}
if(fork()==0)
{
while(1)
{
size=recv(nsfd,buffer,sizeof(buffer),0);
if(size==0)
{
printf("Server is Disconnected...\n");
return;
}
printf("Data:%s\n",buffer);
bzero(buffer,sizeof(buffer));
}
}
else
{
printf("Enter the massage:\n");
signal(17,isr);
while(1)
{
gets(buffer);
send(nsfd,buffer,strlen(buffer)+1,0);
bzero(buffer,sizeof(buffer));
}
}
}
}

Accept() (Winsock 2) stops the program

I have a program that serves both as client and as server without multi-threading (as far as I know accept should let the program continue up until a certain connection is occurs).
The thing is, that my friend has a very similar program (not multithreaded) that also serves as both client AND server and it totally works, I'm trying to accomplish the same thing and accept() stops the program.
The code is as the following:
//main.cpp
#include <iostream>
#include "Client.h"
#include "Server.h"
#pragma comment(lib, "Ws2_32.lib")
int main()
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2,2), &wsaData);
Server s(6666);
Client c("127.0.0.1", 6666);
cout << "Done";
WSACleanup();
return 0;
}
Server.cpp (two variables, SOCKET _socket and struct sockaddr_in _details):
Server::Server(unsigned short Port) : _socket(0)
{
this->_socket = socket(AF_INET, SOCK_STREAM, 0);
if (_socket < 0)
throw "Invalid socket";
ZeroMemory(&this->_details, sizeof(this->_details));
this->_details.sin_family = AF_INET;
this->_details.sin_port = htons(Port);
this->_details.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
if (bind(this->_socket, (const struct sockaddr*)&this->_details, sizeof(this->_details)) != 0)
{
throw "Bind Unsuccessful";
}
this->AcceptConnections();
}
void Server::AcceptConnections()
{
if (listen(this->_socket, SOMAXCONN) != 0)
throw "Listen Unsuccessful";
void* buf = NULL;
string ans("Accepted");
int client;
struct sockaddr_in client_addr;
int addrlen = sizeof(client_addr);
client = accept(this->_socket, (struct sockaddr*)&client_addr, &addrlen);
/*THIS IS WHERE THE PROGRAM STOPS... AWAITING CONNECTIONS*/
//NEVER REACHING THE CODE HERE
int recvBytes = this->Receive(buf, MY_MAX_LEN);
if (recvBytes <= 0)
{
throw "Client disconnected";
}
this->Send((void*)ans.c_str(), ans.length());
closesocket(client);
closesocket(this->_socket);
}
And client.cpp is irrelevant as it doesn't even encounter its code.
Why does this happen? How come my friend has a code with no multi-threading that has both client and server. By the way, Send and Receive are functions implemented by me.

How to use 'getaddrinfo' to choose default free port for all interfaces?

I'm trying to make a server to listen on both IPv4 and IPv6 in dual stack mode.
I want the same port number for both IPv4 and IPv6 servers, and I want it to be on a random selection of port (using port "0")
when I bind, each server get different port, and I want it to be the same.
so I thought it should be done by the getaddrinfo function.
But when I give it the "0" port it stays "0" in the addrinfo results, what cause each bind to give me different port number.
My question: Is there a way to tell the getaddrinfo to select a single free port which is free on all interfaces, then bind the given address to all interfaces?
if there isn't, is there other way to find a free port number? (without binding and stop when fail)
please refer to the following code:
EDIT: now the code can fully compiled on VS 10.
#ifdef WIN32
#include <WS2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#define closesocket close
#endif
#include <iostream>
#include <vector>
#include <stdio.h>
#include <string>
int GetAddressFamily()
{
return AF_UNSPEC;
}
std::string ipaddress(addrinfo* info)
{
std::string retval;
char temp[260];
socklen_t addrlen = (socklen_t)info->ai_addrlen;
int res = ::getnameinfo(info->ai_addr, addrlen, temp, 256, NULL, 0, NI_NUMERICHOST);
if(res){
std::cout<<gai_strerrorA(res)<<std::endl;
}else{
retval = temp;
}
return retval;
}
int getport(addrinfo* info)
{
int retval=0;
if (info->ai_family == AF_INET) {
retval = htons(((struct sockaddr_in*)(info->ai_addr))->sin_port);
}else{
retval = htons(((struct sockaddr_in6*)(info->ai_addr))->sin6_port);
}
return retval;
}
int main()
{
char *hostName = NULL; //GetHostName();
int portNum = 0;
#ifdef WIN32
WSADATA w;
if(0 != WSAStartup(MAKEWORD(2, 2), &w))
{
std::cerr<<" WSAStartup() failed \n";
return -1;
}
#endif
addrinfo hints,*results,*tmp;
memset(&hints,0,sizeof(hints));
hints.ai_family = GetAddressFamily();
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_NUMERICSERV;
if(hostName){
hints.ai_flags |= AI_CANONNAME;
//AI_CANONNAME - fills ai_cannonname in address.
}else{
hints.ai_flags |= AI_PASSIVE;
//AI_PASSIVE - give ADDR_ANY and IN6ADDR_ANY_INIT when hostName is NULL
}
char portbuff[40];
sprintf(portbuff,"%u",portNum);
int res = ::getaddrinfo(hostName, portbuff,&hints, &results);
if(res){
std::cerr<<gai_strerrorA(res)<<std::endl;
}else{
std::vector<int> sockets;
for(tmp = results; tmp ; tmp=tmp->ai_next){
std::cout<<ipaddress(tmp).c_str()<<" : "<<port(tmp)<<std::endl;
int s = socket(tmp->ai_family,tmp->ai_socktype,tmp->ai_protocol);
if(s != -1){
res = bind(s, tmp->ai_addr, (int)tmp->ai_addrlen);
if(res != -1){
sockaddr_storage addr;
socklen_t len =sizeof(addr);
int res = getsockname(s, (struct sockaddr *)&addr, &len);
std::cout<<"Bound to port: ";
if(addr.ss_family == AF_INET){
std::cout<<htons(((sockaddr_in*)&addr)->sin_port)<<std::endl;
}else{
std::cout<<htons(((sockaddr_in6*)&addr)->sin6_port)<<std::endl;
}
sockets.push_back(s);
}
}
}
for(int i=0;i<sockets.size();i++){
closesocket(sockets[i]);
}
}
::freeaddrinfo(results);
return 0;
}
EDIT2: My solution for now:
I added the following function to be called after first successful bind, and will set the given port to addrinfo list:
void setport(addrinfo* info,int port)
{
for(addrinfo* tmp = info; tmp ; tmp=tmp->ai_next){
if (tmp->ai_family == AF_INET) {
((struct sockaddr_in*)(tmp->ai_addr))->sin_port = htons(port);
}else{
((struct sockaddr_in6*)(tmp->ai_addr))->sin6_port = htons(port);
}
}
It should be called after successful bind:
port = getport(result)
//...after bind:
if(port == 0) {
port = printed value after succesful bind
setport(result, port)
}
I think your best option is to use an IPv6 socket with IPV6_V6ONLY disabled. Then that single socket will acccept both IPv6 and IPv4 connections. IPv4 clients will have the address set to the mapped address ::ffff:a.b.c.d.
There's not really any reason to use getaddrinfo here, because you're not looking anything up. Something like this should do it (untested):
int s = socket(AF_INET6, SOCK_STREAM, 0);
if (s < 0)
throw std::system_error(errno, generic_category());
const int off = 0;
if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &off, sizeof(off)) {
close(s);
throw std::system_error(errno, generic_category());
}
struct sockaddr_in6 addr{};
socklen_t alen = sizeof(addr);
if (bind(s, static_cast<struct sockaddr*>(&addr), alen)) {
close(s);
throw std::system_error(errno, generic_category());
}
getsockname(s, static_cast<struct sockaddr*>(&addr), &alen);
int port = ntohs(addr.sin6_port);
PS. It's a good idea to always set the IPV6_V6ONLY option to whichever value you wish, because default varies between OS.

Address Already in Use.

Recently I have been working on some client-side code for sending and receiving messages from a server using threading. The below code behaves strangely when run. Upon inputting a message to send to the server, the code completes the task, albeit with a "socket already in use" error, the server gets it. But every subsequent message I attempt to send to the server is not received immediately, yet it is seemingly all received at once when the client program terminates.
(Additionally, I am certain the error is client-side, the strange behavior isn't exhibited if one comments the output function.)
How can I fix this error?
Client
#include <stdio.h>
#include <cstdlib>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <unistd.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <string>
#include <iostream>
#include <errno.h>
#include <pthread.h>
void* input(void* ptr)
{
int on = 1;
bool *input_done = ((struct thread_args*)ptr)->process_done;
struct addrinfo *res = ((struct thread_args*)ptr)->result;
char msg[256];
int sock = socket(res->ai_family,res->ai_socktype,res->ai_protocol);
setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(char *)&on,sizeof(on));
bind(sock,res->ai_addr,res->ai_addrlen);
connect(sock,res->ai_addr,res->ai_addrlen);
cin.getline(msg,256);
if (msg[0] == '/') {exit(1);}
send(sock,msg,sizeof msg,0);
cout << "You:" << msg << endl;
*input_done = 1;
close(sock);
pthread_exit(NULL);
}
void* output(void* ptr)
{
int on = 1;
bool *output_done = ((struct thread_args*)ptr)->process_done;
struct addrinfo *res = ((struct thread_args*)ptr)->result;
char msg[256];
int sock = socket(res->ai_family,res->ai_socktype,res->ai_protocol);
bind(sock,res->ai_addr,res->ai_addrlen);
connect(sock,res->ai_addr,res->ai_addrlen);
recv(sock,msg,sizeof msg,0);
cout << "Recieved:" << msg;
*output_done = 1;
close(sock);
pthread_exit(NULL);
}
void io_client()
{
//thread function variables
pthread_t t1,t2;
bool input_done = 1, output_done = 1;
//socket setup variables
struct addrinfo hints, *res;
memset(&hints,0,sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
getaddrinfo("localhost","8080",&hints,&res);
//setting up structures to pass data to threaded functions
struct thread_args i_args, o_args;
i_args.result = res; i_args.process_done = &input_done;
o_args.result = res; o_args.process_done = &output_done;
while(1)
{
if (output_done)
{
pthread_create(&t2,NULL,output,&o_args);
output_done = 0;
}
if (input_done)
{
pthread_create(&t1,NULL,input,&i_args);
input_done = 0;
}
}
}
int main()
{
io_client();
}
Server
void server()
{
struct addrinfo hints, *res;
int sock=-1, newsock=-1;
int length, on=1;
char **address_list; int entries = 0;
//fd_set read_fd;
//struct timeval timeout;
char buffer[100];
memset(&hints,0,sizeof hints);
res = NULL;
memset(&res,0,sizeof res);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
getaddrinfo("localhost","8080",&hints,&res);
sock = socket(res->ai_family,res->ai_socktype,res->ai_protocol);
setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(char *)&on,sizeof(on));
bind(sock,res->ai_addr,res->ai_addrlen);
listen(sock,10);
while(1)
{
struct sockaddr_storage addr;
char ipstr[INET6_ADDRSTRLEN];
socklen_t len;
len = sizeof addr;
newsock = accept(sock,NULL,NULL);
getpeername(newsock,(struct sockaddr*)&addr,&len);
struct sockaddr_in *s = (struct sockaddr_in*)&addr;
inet_ntop(AF_INET,&s->sin_addr,ipstr,sizeof ipstr);
length = 100;
setsockopt(newsock,SOL_SOCKET,SO_RCVLOWAT, (char*)&length,sizeof length);
recv(newsock,buffer,sizeof buffer,0);
cout << buffer << endl;
}
if (newsock != -1)
{
close(newsock);
}
if (sock != -1)
{
close(sock);
}
}
int main()
{
server();
}
It looks like you are trying to have your client bind() to the same port as the server. That's not necessary. And worse, you are trying to bind to to the IP address of the server - which is also a bigger problem. In general, for client sockets that are to call the connect() function, you should just have your socket bind to port 0 and IP 0, thus letting the OS pick a randomly available port for you and enabling use the right local IP address and adapter for the connection. You can call getsockname() to discover what port the OS picked for you after you call connect.
And if you let the OS pick the client port for you, you won't need that SO_REUSESADDR call. Although, your server code could call it for cases where it needs to restart after shutting down with connections still pending to close.
Also. you aren't checking the return value of any of your socket calls. That's probably why you are getting some mysterious results. The call to bind() is more likely failing because you are specifying the server IP, but connect() is succeeding because it will auto-bind the socket if it hasn't already.
Here's a cleaned up version of you input() function. Converting your output() function is an exercise left up to the reader. If you follow my example, you'll be in good shape.
void* input(void* ptr)
{
int on = 1;
bool *input_done = ((struct thread_args*)ptr)->process_done;
int ret;
int success = true;
struct sockaddr_in addrLocal = {};
struct addrinfo *res = ((struct thread_args*)ptr)->result;
char msg[256];
int sock = socket(AF_INET, SOCK_STREAM, 0);
success = (sock != -1);
if (success)
{
addrLocal.sin_family = AF_INET;
addrLocal.sin_port = INADDR_ANY; // INADDR_ANY == 0 --> pick a random port for me
addrLocal.sin_addr.s_addr = INADDR_ANY; // INADDR_ANY == 0 --> use all appropriate network
ret = bind(sock,(sockaddr*)&addrLocal,sizeof(addrLocal));
if (ret == -1) perror("bind: ");
success = (ret != -1);
}
if (success)
{
ret = connect(sock,res->ai_addr,res->ai_addrlen);
if (ret == -1) perror("connect: ");
success = (ret != -1);
}
if (success)
{
cin.getline(msg,256);
if (msg[0] == '/') {exit(1);}
ret = send(sock,msg,sizeof msg,0);
if (ret == -1) perror("send: ");
success = (ret != -1);
}
if (success)
{
cout << "You:" << msg << endl;
*input_done = 1;
}
if (sock != -1)
{
close(sock);
sock = -1;
}
return NULL;
}
I guess that "SO_REUSEADDR" socket option that you are giving is the problem.
Are you calling that function again and again without closing the client socket ? In that case it will not work. The purpose of this socket option is to "reuse the address when the already opened socket for the same address is in TIME_WAIT state else you will get the mentioned error".
If you client is opening a new connection each and every time, then I must say that you will have to structure your code more efficiently and handle the socket closing scenarios as well.