• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
password

Multithreaded server in C++ and Win32

10 posts in this topic

I've been searching around for about 4 hours now about how to implement Winsock in a threaded program. I didn't find anything good at all, only a bunch of weird examples that doesn't actually work or use Winsockets. How can I structure my program so I can handle many clients at once? My code so far is good enough to handle one client. Right now it looks something like this.
	WSADATA wsaData;
	SOCKET ListenSocket;
    int iResult;

    struct addrinfo *result = NULL,
                *ptr = NULL,
                hints;

    // initiera Winsock
    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (iResult != 0) {
		std::cout << "WSAStartup failed: " << iResult << std::endl;
    }

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

    iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
    if (iResult != 0) {
		std::cerr << "getaddrinfo failed: " << iResult << std::endl;
        WSACleanup();
    }

	ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
    if (ListenSocket == INVALID_SOCKET) {
		std::cerr << "Error at socket(): " << WSAGetLastError() << std::endl;
        freeaddrinfo(result);
        WSACleanup();
    }

    iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
    if (iResult == SOCKET_ERROR) {
		std::cout << "bind failed: " << WSAGetLastError() << std::endl;
        freeaddrinfo(result);
        closesocket(ListenSocket);
        WSACleanup();
    }

    freeaddrinfo(result);

    if (listen(ListenSocket, SOMAXCONN ) == SOCKET_ERROR) {
		std::cout << "Error at bind(): " << WSAGetLastError();
        closesocket(ListenSocket);
        WSACleanup();
    }

	SOCKET ClientSocket = INVALID_SOCKET;

    // accepterar för tillfället bara en anslutning från klientsidan
    ClientSocket = accept(ListenSocket, NULL, NULL);
    if (ClientSocket == INVALID_SOCKET) {
        printf("accept failed: %d\n", WSAGetLastError());
        closesocket(ListenSocket);
        WSACleanup();
    }

    // closesocket(ListenSocket);

    char recvbuf[DEFAULT_BUFLEN];
    int iSendResult;
    int recvbuflen = DEFAULT_BUFLEN;

	// ta emot paket tills den anslutade stänger av sin anslutning
    do {
		iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
        if (iResult > 0) {
			std::cout << "Bytes received: " << iResult << std::endl;

            // Echo the buffer back to the sender
            iSendResult = send(ClientSocket, recvbuf, iResult, 0);
            if (iSendResult == SOCKET_ERROR) {
				std::cout << "send failed: " << WSAGetLastError() << std::endl;
                closesocket(ClientSocket);
                WSACleanup();
                return 0;
            }

		std::cout << "Bytes sent: " << iSendResult << std::endl;

	} else if (iResult == 0) {
		std::cout << "Connection closing.. " << std::endl;

	} else {
		std::cout << "recv failed: " << std::endl;
        closesocket(ClientSocket);
        WSACleanup();
        return 0;
    }

    } while (iResult > 0);

    // shutdown the send half of the connection since no more data will be sent
    iResult = shutdown(ClientSocket, SD_SEND);
	if (iResult == SOCKET_ERROR) {
		std::cout << "shutdown failed: " << WSAGetLastError() << std::endl;
        closesocket(ClientSocket);
        WSACleanup();
        return 0;
    }
Thankful for help. I've been trying everything I can.
0

Share this post


Link to post
Share on other sites
Hi password

I recently took a close look at boost::asio. And I have to say it's really smooth. I really like it. Also there are plenty of examples that deal with severeal standard networking scenarios. Maybe it could be a usefull for you.

Best Jochen
0

Share this post


Link to post
Share on other sites
Oh, and just in case you don't know boost, here is a direct link
http://boost.org/doc/libs/1_35_0/doc/html/boost_asio.html.

Best
Jochen
0

Share this post


Link to post
Share on other sites
Quote:
Original post by jochen
Hi password

I recently took a close look at boost::asio. And I have to say it's really smooth. I really like it. Also there are plenty of examples that deal with severeal standard networking scenarios. Maybe it could be a usefull for you.

Best Jochen


Nice one, that's even pure C++, I missed that from Win32 which was mostly coded in C. I'll take a look into that library.
0

Share this post


Link to post
Share on other sites
Hi password,
I hope you don't mind I reply in the public section... maybe this info is interesting for some others, too.

There is a very comprehensive "Getting Started Guide" that I recommend to work through.

Well here is how I "boost":

To keep track of changes easily I use tortoise to connect to subversion and update from time to time. In case you dont know these, simply google for "tortoise or/and subversion".

You can find a detailed description on how to setup access to subversion here.

So now that you have the boost sources and bjam on your HD, you will have to build. Simply fire up a MSVC command shell and issue bjam. Since I do this quite often I created two batch files.

JamIt32.bat for 32 bit builds:
bjam --build-dir=E:\Temp\build-boost\x86 --toolset=msvc-9.0 --build-type=complete --prefix=D:\Development\3rdParty\boost --libdir=D:\Development\3rdParty\boost\Lib\x86 --without-python --without-wave install

and JamIt64.bat for 64 bit builds:
bjam address-model=64 --build-dir=E:\Temp\build-boost\x64 --toolset=msvc-9.0 --build-type=complete --prefix=D:\Development\3rdParty\boost --libdir=D:\Development\3rdParty\boost\Lib\x64 --without-python --without-wave install

Now sit back, since this will take some time. Hint: Don't forget to use a 64bit MSVC command shell to build the 64bit version and of course you will have to adjust the paths to match your system.

Now you should have a ready to use boost version on your system.

To manage include paths, I use the Property Sheets feature of Visual Studio.
These are quite usfull, if you are tired of setting up the same include paths in any new prject over and over again. MSDN has good documentation on that: Property Sheets (C++).

You don't need to explicitely link against boost libs, because most of them are header only anyways. And the non header only libs are autolinked via pragmatas.

Well finally there is one thing expecially in case you intend to use asio:
Documentation. Building boost documentation is imho a tricky thing and therefore I prefer online documentation. However in case you don't have constant internet access, simply download a release package from time to time.

Also: Version 1.35 has just been released. But I think in a few weeks you will find a 1.35 boost msi here: boost consulting

I hope this is somehow usefull for you. In case not, simply drop me a line and I will do my best to supply more/better information.

Well finally enjoy boost::asio. Which imho makes network programming really fun.

Best
Jochen



0

Share this post


Link to post
Share on other sites
There was a lot of those steps I didn't understand, but i've done the following now.

1. Extracted the latest .rar of Boost into the following folder.
"C:\Program Files\boost\boost_1_35_0"

2. Downloaded bjam and opened its *build file and it did something (have no idea). Now when i'm trying to issue the commands like this one: bjam --build-dir=build-directory --toolset=toolset-name stage

It doesn't find bjam. It can only find it when I type "bjam ^".


> bjam ^
> More?
> More? --help
> 'bjam' is not a recognized command...

The same happens when I use this command.

> bjam --build-dir=build-directory --toolset=toolset-name stage
> 'bjam' is not a recognized command...


Sorry, but it feels like they intentionally made it as hard as it can be to install this library. I don't have a clue what to do, thanks for writing all that stuff up though.

Isn't it possible to just download all of the .lib files? Right now the only thing I miss are the lib files.
0

Share this post


Link to post
Share on other sites
You could create a thread for each incoming connection.
Here is some pseudo code (without error detection or cleanup code)


...
while(server_is_still_running)
{
// Wait for the next client to connect
clientSocket = accept(...);

// Spawn a thread to deal with the new client
CreateThread(..., ThreadFunc, (void*)clientSocket);
}

int WINAPI ThreadFunc(VOID* arg)
{
int* pClientSocket = (int*)arg;

// use send/recv here to communicate with this socket...
}




edit:
If you don't want to go with threads you should be able to deal with multiple clients by using the select call. select can be tricky to handle right but it can be used to everything from detecting new connections to dealing with existing ones in an asynchronous manner.

[Edited by - pulpfist on April 3, 2008 5:30:25 PM]
0

Share this post


Link to post
Share on other sites
Before you do anything, I suggest you learn about threading first. Learn about critical sections/mutexes/semaphores/etc. first and then incorporate winsock in to that. You need a good background in multithreading before you start messing with multithreaded servers as they are quite complex. MSDN is your best bet to look at. If you need help, you can pm me.
0

Share this post


Link to post
Share on other sites
hi password,

If u have the latest package installed extracted to C:\Program Files\boost\boost_1_35_0, do the following:

Copy bjam.exe to this directory, too.
Start a MSVC command shell.
type cd "C:\Program Files\boost\boost_1_35_0"
type (all in one line) bjam --build-dir=E:\Temp\build-boost\x86 --toolset=msvc-9.0 --build-type=complete --prefix=D:\Development\3rdParty\boost --libdir=D:\Development\3rdParty\boost\Lib\x86 --without-python --without-wave install

I hope this works for u.

Best Jochen
0

Share this post


Link to post
Share on other sites
Quote:
Original post by jochen
hi password,

If u have the latest package installed extracted to C:\Program Files\boost\boost_1_35_0, do the following:

Copy bjam.exe to this directory, too.
Start a MSVC command shell.
type cd "C:\Program Files\boost\boost_1_35_0"
type (all in one line) bjam --build-dir=E:\Temp\build-boost\x86 --toolset=msvc-9.0 --build-type=complete --prefix=D:\Development\3rdParty\boost --libdir=D:\Development\3rdParty\boost\Lib\x86 --without-python --without-wave install

I hope this works for u.

Best Jochen


Great, it worked now. It created a directory named boost with the following folders.


| build-boost
| x86
| boost
| bin.v2
| libs
| lots of maps here

| Lib
| x86
| lots of .lib files here


Another question (hopefully my last one). The boost directory that was created, am I supposed to add it directly into the lib/ folder of the IDE so I get: MSVC/VC++/lib/boost/...?
0

Share this post


Link to post
Share on other sites
Quote:
Original post by password

Another question (hopefully my last one). The boost directory that was created, am I supposed to add it directly into the lib/ folder of the IDE so I get: MSVC/VC++/lib/boost/...?


Tools/Options/Projects and Solutions/VC++ Directories

Then add the paths to "Include files" and "Library files". This will give your entire IDE access to boost.

Boost libraries use auto-linking, so no additional configuration is needed, no matter how you build your applications.
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0