SDL_net Tutorials or code

Started by
9 comments, last by flodihn 13 years, 4 months ago
I have looked everywhere for decent tutorial or sourcecode for how to use the networking library SDL_net but I didn't manage to find anything to learn from.

I found the tutorial http://gpwiki.org/index.php/SDL:Tutorial:Using_SDL_net not helpful at all and when I try to run the program, it uses allot of memory and the whole PC run's very slowly.

I hope someone could help me with this.

thankyou in advance.
Advertisement
Don't use SDL_Net, then? Or use the debugger to figure out what's going on?

Btw: if you're having trouble with very simple tutorials, why do you have a "game company" and are "looking for people"? What does that even mean? I suggest you ask someone who knows that they're doing to help you plot a course to get to where you want to go. With a good plan, and a willingness to follow the plan for many years (and not skip ahead), you can really get where you want to go.

From your questions on this forum, I would suggest first learning your programming language, your operting system, and your development tools *well*. This includes things like data structures and algorithms, as well as things like pointers, arrays, templates, abstract classes and other methods of abstractions. You also want to know how things like memory management, files, asynchronous I/O, processes, threads, and locks work for your OS. These are the kinds of things people learn when taking CS in college, so you should expect to spend several years on that step.

*Then* you can start trying to get into applications skills like 3D data representations (needed for physics and graphics), collision testing and integration (physics), transform and shading (graphics), distributed systems (network programming) etc.

There really is no short-cut.

Or, you can use something where a lot of people who have already learned the trade have done all the hard parts for you, and actually build a game. I recommend one of the following:
Unreal Development Kit (for first-person shooters)
Unity 3D (for anything else)
C4 Engine (if you can spend a few hundred and like C++ programming)
enum Bool { True, False, FileNotFound };
are you stupid :@
that game company recruiting has nothing to do with the thread. it is a signature.

if you don't want to help then don't comment.

who said I don't know nothing about programming and all the stuff you listed. I was just wondering if there are any good tutorials around for SDL_net. whats networking got to do with 3d and collission and who said I don't know any of them?

you don't sound very proffessional yourself. you are meant to be a moderator to help people and stop people flaiming on threads but you are the one who's flaiming me.

anyway if someone is willing to help me and many others who are in the same situation looking for guidance for SDL_net then please comment thankyou
The problem you are having is quite elementary, if you hope to write a real networked program then you should be able to solve this. This is the essence of hplus0603's point.

Basically, the program is written to look for new connection requests as fast as possible. On a single processor machine, this will soak up all the available CPU. On my system the server uses a tiny amount of memory.

The tutorial appears to be reasonably helpful, I cannot see why you think it is no help at all. You cannot expect to find a tutorial that is 100% identical to what you want to do - you will always have to adapt, extend and embed it into your existing system.
I have copied the tutorial from there and it works but I think there is a memory leak in it because it uses allot of my CPU.

I understand the code but it is always very helpful to see more than just one tutorial to understand fully what is happening and to see the best way to emplement it.

anyway I have figured out this and I now am looking at some sourcecode for it.

thankyou anyway for your time.
High CPU usage does not imply memory leaks.

As for the program using a lot of your CPU - of course it will. You're not using it for anything else, so the scheduler keeps running the server as fast as it can. You would be annoyed if your OS failed to give as much processing power as it had to your newest game purchase!

If you want your application to play nice with other processes, then you'll need to write extra code to do so. Tutorials usually leave out all such strictly unnecessary code, so they can focus on what they are presenting.

If you want to understand what is happening, then the Multiplayer and Network Programming FAQ is the place to start. I recommend the link "Beej's Networking Tutorials". They won't help you directly with SDL_Net, but the concepts are there and the code can be coverted to use SDL_Net's functions (SDL_Net's functions are just a thin wrapper around the code presented, anyway).
SDL_net is not hard. Try learning Berkeley Sockets. ;)
Amateurs practice until they do it right.Professionals practice until they never do it wrong.
Quote:
if you don't want to help then don't comment.


The thing is, I gave you the absolutely best help that you can get right now. You just don't seem ready to absorb it.
enum Bool { True, False, FileNotFound };
So, sadly, it doesn't seem like you are getting a lot of help here. I've actually done some sdl_net coding on a network library in the past few months, so I'd be happy to give some code.

First, though, what exactly are you trying to accomplish? What sorts of data/rates are you after? I'll need that to give you a useful answer.
Here is my SDL_Net code I using in my client, basically what it does is allow you to establish a single connection to a server using the function connect("server.name.com", 2000).

Then you can send data to the server by using protocolSend("csdf", 1, "HelloWorld", 13, 45.367) for example.

It also has a function recvHeader() if it returns something else then 0, it means that amount of byte is ready to be received :)
Then you can run call the function recvData to get that information.

Connection.h
#ifndef ABYDOS_CONNECTION_H#define ABYDOS_CONNECTION_H#include <SDL/SDL_net.h>#include <string>#include "byte.h"#define ERLANG_INT_SIZE 1#define ERLANG_DOUBLE_SIZE 8namespace Abydos {class Connection{    public:    static Connection *getSingleton();        Connection();    ~Connection();        bool connect(std::string, int port);    void disconnect();    bool isConnected();    void sendHeader(short size);    void sendData(const char* data, int len);    void protocolSend(const char *fmt, ...);    double protocolReadDouble(byte *data, int *index);    signed int protocolReadInt(byte *data, int *index);    std::string protocolReadString(byte *data, int *index);    int recvHeader();    void recvData(int *evendId, byte *data, int len);        private:    void memcopy(byte *source, byte* dest, int start, int length);    void protocolReadBytes(byte *source, byte *dest, int start,         int end);	    IPaddress mIp;         TCPsocket mSock;    SDLNet_SocketSet mSet;	    bool mConnected;    int mQuit, mLen;    char mBuffer[512];};}#endif


Connection.cpp
// Do I really need all those to get htons?#ifdef WIN32#include <winsock2.h>#else#include <netdb.h>#include <sys/types.h>#include <netinet/in.h>#include <sys/socket.h>#include <arpa/inet.h>#endif#include <iostream>#include <sstream>#include <cstdarg>#include <SDL/SDL.h>#include <SDL/SDL_net.h>#include "Connection.h"#include "debug.h"using namespace std;using namespace Abydos;Connection *Connection::getSingleton() {    static Connection inst;    return &inst;}Connection::Connection(){    if(SDL_Init(0)==-1) {        debug("SDL_Init: %s\n", SDL_GetError());        exit(1);    }        if(SDLNet_Init()==-1) {        debug("SDLNet_Init: %s\n", SDLNet_GetError());        exit(2);    }    mConnected = false;}Connection::~Connection(){}bool Connection::connect(string host, int port){    if(mConnected)        return true;    SDLNet_ResolveHost(&mIp, host.c_str(), port);    mSock = SDLNet_TCP_Open(&mIp);    if(mSock == 0) {        return false;    }        mSet = SDLNet_AllocSocketSet(1);    SDLNet_TCP_AddSocket(mSet, mSock);    mConnected = true;    return true;}void Connection::disconnect() {    if(mConnected)        SDLNet_TCP_Close(mSock);    mConnected = false;}bool Connection::isConnected() {    return mConnected;}void Connection::sendHeader(short size){    short netShort = htons(size);    int sent;    sent = SDLNet_TCP_Send(mSock, (const void*) &netShort, 2);    if(sent < 2) {        debug("SDLNet_TCP_Send Header: %s, sent %d", SDLNet_GetError(),            sent);    }}void Connection::sendData(const char *data, int len){    sendHeader((short) len);    int sent = SDLNet_TCP_Send(mSock, (const void*) data, len);    if(sent  < len) {        debug("SDLNet_TCP_Send Data: %s", SDLNet_GetError());    }}int Connection::recvHeader() {    int numReady;    short header;    short *header_ptr = &header;    int received;    numReady = SDLNet_CheckSockets(mSet, 0);        if(numReady == -0)         return 0;       received = SDLNet_TCP_Recv(mSock, header_ptr, 2);            if(received < 1)        return 0;    return (int) ntohs(header);}void Connection::recvData(int *eventId, byte* data, int dataSize) {    int left = dataSize;    int received = 0;    int numBytes;        byte chunk[dataSize - 1];    byte buffer[dataSize - 1];    while(received < dataSize) {        memset(chunk, 0, dataSize);        numBytes = SDLNet_TCP_Recv(mSock, &chunk, left);        memcopy(chunk, buffer, received, received + numBytes - 1);        if(numBytes == 0) {            debug("Connection closed");        } else if(numBytes < 0) {            debug("Fatal network error");        } else {            received += numBytes;            left -= numBytes;        }    }    char foo = buffer[0];    *eventId = (int) foo;    if(dataSize > 1) {        memcopy(buffer, data, 1, dataSize -1);    }}void Connection::memcopy(byte *source, byte* dest, int start, int length) {    int memIndex = 0;    for(int i = start; memIndex <= length; i++) {        dest[memIndex] = source;        memIndex++;    }   }void Connection::protocolSend(const char *fmt, ...) {    va_list argp;    int len = 0;    const char *c;    va_start(argp, fmt);    stringstream buffer(stringstream::in | stringstream::out |        stringstream::binary);    for(c = fmt; *c != '\0'; c++) {        if(*c == 'c') { //char            char tmp = (char) va_arg(argp, int);            buffer.write(&tmp, sizeof(char));            len += sizeof(char);        } else if(*c == 'd') { //integer            short tmp = (short) va_arg(argp, int);            short networkTmp = htons(tmp);            buffer.write((char*) &networkTmp, sizeof(short));            len += sizeof(short);        } else if(*c == 's') { //string            string tmp = va_arg(argp, char *);            char length = (char) tmp.length();            buffer.write(&length, sizeof(char));            buffer.write(tmp.c_str(), tmp.size());            len += sizeof(char) + tmp.size();        } else if(*c == 'f') { //double            double tmp =  va_arg(argp, double);            buffer.write((char *)&tmp, sizeof(double));            len += sizeof(double);        } else if(*c == 'r') {  //raw            int size  = va_arg(argp, int);            unsigned char *tmp = va_arg(argp, unsigned char *);            char length = (char) size;            buffer.write((const char*) &length, sizeof(char));            buffer.write((const char*) tmp, size);            len += size + 1;        }    }    va_end(argp);    sendData(buffer.str().c_str(), len);}string Connection::protocolReadString(byte *data, int *index){    int len = data[*index];    byte str[len];    protocolReadBytes(data, str, *index + 1, *index + len);    str[len] = '\0';    *index += 1 + len;    return string((const char *) str);}signed int Connection::protocolReadInt(byte *data, int *index){    /* FIX DYNAMIC 2-BYTE-CHAR/4-BYTE-INTS LATER */    byte t;    protocolReadBytes(data, &t, *index, *index + ERLANG_INT_SIZE - 1);    *index = *index + ERLANG_INT_SIZE;    char dest2 = (char) t;    return dest2;}double Connection::protocolReadDouble(byte *data, int *index){    double d;    protocolReadBytes(data, (byte*) &d, *index,        *index + ERLANG_DOUBLE_SIZE - 1);    *index = *index + ERLANG_DOUBLE_SIZE;    return d;}void Connection::protocolReadBytes(byte *source, byte *dest,     int start, int end){    int index = 0;    for(int i = start; i <= end; i++) {        dest[index] = source;        index++;    }}

This topic is closed to new replies.

Advertisement