Click here to Skip to main content
15,885,546 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
main function:
C++
#include <iostream>
#include <cstdlib>
#include "server.h"
#include <windows.h>
using namespace std;

int main()
{
    Object_server a;
    Sleep(10000);

    return 0;
}


this is server.h:
C++
#ifndef SERVER_H_INCLUDED
#define SERVER_H_INCLUDED

#include <winsock2.h>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <process.h>
#include <windows.h>
#include <stdio.h>
using namespace std;

class Object_server
{
private:

    bool bool_server_flag;
    WSADATA wsaData;
    int socket_counter;
    struct Object_socket
    {
        SOCKET socket_Local;
        SOCKET *socket_Remote;
    };
    struct Object_socketaddr
    {
        struct sockaddr_in sockaddr_Local;
        struct sockaddr_in *sockaddr_Remote;
    };

    struct Object_Data_transmission
    {
        int int_counter;
        int total;
        vector <int> int_target;//-1 server -2NULL
        vector <string> str_Data;
    };

    Object_socket O_socket;
    Object_socketaddr O_sockaddr;
    Object_Data_transmission *O_Data_transmission;
    bool server_on(int int_port=11111)
    {
        int int_flag;

        if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
        {
            return false;
        }

        O_socket.socket_Local=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

        if(O_socket.socket_Local==INVALID_SOCKET)
        {
            return false;
        }

        O_sockaddr.sockaddr_Local.sin_family=AF_INET;
        //O_sockaddr.sockaddr_Local.sin_addr.s_addr=inet_addr(PC_DATA.get_Ip());
        O_sockaddr.sockaddr_Local.sin_addr.s_addr=inet_addr("127.0.0.1");
        O_sockaddr.sockaddr_Local.sin_port=htons(int_port);
        //O_sockaddr.sockaddr_Local.sin_zero=NULL;



        int_flag=bind(O_socket.socket_Local,(struct sockaddr *)&O_sockaddr.sockaddr_Local,sizeof(O_sockaddr.sockaddr_Local));
        if(int_flag!=0)
        {
            return false;
        }

        int_flag=listen(O_socket.socket_Local,128);
        if(int_flag!=0)
        {
            return false;
        }

        O_socket.socket_Remote=new SOCKET[128];
        O_sockaddr.sockaddr_Remote=new sockaddr_in[128];
        O_Data_transmission=new Object_Data_transmission[128];

        socket_counter=0;

        bool_server_flag=true;

        //_beginthread(Object_server::accept_thread,0,(void *)this);
        unsigned threadID;

        int_flag=_beginthreadex(NULL,0,Object_server::accept_thread,(void *)this,CREATE_SUSPENDED,&threadID);
        //cout<<int_flag;
        //accept_thread((void *)this);
        return true;

    }

    static unsigned __stdcall accept_thread(void *ptr)
    {
        static_cast<Object_server *>(ptr)->accept_f();
        return 0;
    }

    void accept_f()
    {

        int sockaddr_size;

        while(bool_server_flag)
        {

            sockaddr_size=sizeof(O_sockaddr.sockaddr_Remote[socket_counter]);
            O_socket.socket_Remote[socket_counter]=accept(O_socket.socket_Local,(struct sockaddr *)&O_sockaddr.sockaddr_Remote[socket_counter],&sockaddr_size);

            if(O_socket.socket_Remote[socket_counter]!=INVALID_SOCKET)
            {
                ++socket_counter;
                cout<<"connect : "<<socket_counter<<'\n';

            }
            else
            {
                cout<<"connect failed"<<'\n';
            }
        }


    }

public:
    Object_server()
    {
        bool_server_flag=false;

        while(server_on())
        {

        }
    }

    Object_server(int int_port)
    {
        bool_server_flag=false;

        while(server_on(int_port))
        {

        }
    }
    ~Object_server()
    {
        delete []O_socket.socket_Remote;
        delete []O_sockaddr.sockaddr_Remote;
        delete []O_Data_transmission;
    }

};

#endif // SERVER_H_INCLUDED


something are abnormal
if i use thread(_beginthreadex or _beginthread)
the function accept_f run strange
1.all the function "cout" didn't show on the screen
2.the socket_counter haven't added
3.the client haven't connect but it didn't pause on the function "accept"

and even it run like that but the client can connect to server

client code
C++
>#define  IP_ADDRESS "127.0.0.1"
using namespace std;

int PORT=11111;

WSADATA wsd;
SOCKET cClient;
int ret;
struct sockaddr_in server;

hostent *host=NULL;

int main()
{

    //cin>>PORT;
    if( WSAStartup(MAKEWORD(2,0),&wsd) )
	{
		return 0;
	}

    cClient = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

    if( cClient == INVALID_SOCKET)
	{
		return 0;
	}
    server.sin_family = AF_INET;
    server.sin_port = htons(PORT);
    server.sin_addr.s_addr = inet_addr(IP_ADDRESS);
    if(server.sin_addr.s_addr == INADDR_NONE)
	{
		return 0;
	}
    connect(cClient,(struct sockaddr *)&server,sizeof(server));
    printf("start to connect!\n")
Posted
Updated 23-Jul-13 18:51pm
v2

1 solution

This call;

C++
int_flag=_beginthreadex(NULL, 0, Object_server::accept_thread, (void *)this, CREATE_SUSPENDED, &threadID);

Creates the accept thread in suspended state, you'll either have to start the thread manually by calling ResumeThread after that or, change the CREATE_SUSPENDED to 0, like this;

C++
int_flag=_beginthreadex(NULL, 0, Object_server::accept_thread, (void *)this, 0, &threadID);


That should at least start your accept thread and you will see the cout prints from the server.

Hope this helps,
/Fredrik
 
Share this answer
 
Comments
Ken Chiayuan Chang 24-Jul-13 4:11am    
thank you. i can show something on the screen.but the function accept is still incorrect.
Fredrik Bornander 24-Jul-13 5:17am    
Then you should mark this answer as Accepted and ask a new one relating to your new problem.
/Fredrik
Ken Chiayuan Chang 24-Jul-13 17:40pm    
but the question
2.the socket_counter haven't added
3.the client haven't connect but it didn't pause on the function "accept"
haven't solved already~
but thank you for help
Fredrik Bornander 26-Jul-13 3:03am    
Your code is a bit messy so I can't figure out exactly what's wrong but here's a working example of a multithreaded socket server;

server.hpp
#pragma once

#include <vector>
#include <exception>
#include <sstream>
#include <ws2tcpip.h>
#include <process.h>
#include <winsock2.h>

#pragma comment (lib, "Ws2_32.lib")

std::string int_to_str(const int value)
{
std::stringstream ss;
ss << value;
return ss.str();
}


class server;

struct thread_start_data
{
server* server;
unsigned int (__stdcall *handler_func)(void*);
};


class server
{
private:
SOCKET listen_socket;
std::vector<socket> client_sockets;
bool should_listen;

public:
// Constructs, get address, create socket and bind socket
server(const int port);

// Destructs, and cleans up a bit
~server();

void accept_client(unsigned int (__stdcall *handler_func)(void*));

// Call this to spawn a new thread listening for incoming connections, if one is made
// handle_func will be called with the SOCKET as a single parameter
void start(unsigned int (__stdcall *handler_func)(void*));

// Tells the server to stop listen and close the listner socket
void stop();
};

server::server(const int port)
{
try
{
WSADATA wsaData;
int r = WSAStartup(MAKEWORD(2, 2), &wsaData);

struct addrinfo *result = 0;
struct addrinfo *ptr = 0;
struct addrinfo hints;

ZeroMemory(&hints, sizeof (hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;

int iResult = getaddrinfo(NULL, int_to_str(port).c_str(), &hints, &result);
if (iResult != 0) {
throw std::exception("failed to get address info", iResult);
}

listen_socket = INVALID_SOCKET;
listen_socket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);

if (listen_socket == INVALID_SOCKET) {
freeaddrinfo(result);
throw std::exception("failed to aquire socket", WSAGetLastError());
}

iResult = bind(listen_socket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR)
{
freeaddrinfo(result);
closesocket(listen_socket);
throw std::exception("failed to bind socket", WSAGetLastError());
}

freeaddrinfo(result);
}
catch(...)
{
WSACleanup();
throw;
}
}

server::~server()
{
for(std::vector<socket>::iterator it = client_sockets.begin(); it != client_sockets.end(); ++it)
{
closesocket(*it);
}
WSACleanup();
}


void server::accept_client(unsigned int (__stdcall *handler_func)(void*))
{
if (listen(listen_socket, SOMAXCONN ) == SOCKET_ERROR)
{
throw std::exception("failed to listen on socket", WSAGetLastError());
}

while(should_listen)
{
// If successfully connected, it's the handler_func's responsibility to delete this!
SOCKET* client_socket = new SOCKET;
*client_socket = INVALID_SOCKET;

*client_socket = accept(listen_socket, NULL, NULL);
if (*client_socket == INVALID_SOCKET) {
delete client_socket;
throw std::exception("failed to accept client connection", WSAGetLastError());
}

client_sockets.push_back(*client_socket);

unsigned thread_id;

// Start thread handling the client socket
uintptr_t thread_result = _beginthreadex(0, 0, handler_func, client_socket, 0, &thread_id);
}
}


static unsigned __stdcall accept_thread(void *info)
{
thread_start_data start_data = *reinterpret_cast<thread_start_data*>(info);
start_data.server->accept_client(start_data.handler_func);
return 0;
}


void server::start(unsigned int (__stdcall *handler_func)(void*))
{
thread_start_data* info = new thread_start_data;
info->server = this;
info->handler_func = handler_func;
unsigned thread_id;

uintptr_t thread_result = _beginthreadex(0, 0, accept_thread, info, 0, &thread_id);
}

// Tells the server to stop listen and close the listner socket
void server::stop()
{
should_listen = false;
closesocket(listen_socket);
}



program.cpp
#include "server.hpp"
#include <iostream>

// This is an example cli
Ken Chiayuan Chang 5-Aug-13 21:55pm    
thanks a lot~~~
you solve a big problem

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900