Trying to do socket coding

Started by
9 comments, last by Kylotan 18 years, 5 months ago
Im trying to get into network programming and sockets seems a good place to start. But to try out a socket client I need some kind of server, and coding both client and server myself leaves a bit to much out to get wrong. I think it easier if I only have to code the client (at start). Is there somewhere, some kind of server that just echoes back whatever it recieves? So I can check if I connect/read and send in the right way? Or if it someone who has already coded a application server like that and is willing to give it to me so I can run it locally. Thanks in advance. :)
Advertisement
Beej's guide to network programming contains the code of servers and clients. It mostly targets unix socket programming (winsock programming is not very different; in fact, it is mostly the same).

The world of select is another tutorial that contains the code of a server - again, it is unix-oriented.

SDL has a networking API that can ease the writing of both the client and the server. Moreover, it comes with a a concrete sample: a chat server and its client.

RakNet is a corss-platform networking API that really ease the creation of UDP client/server applications. The tutorial shows how to create a simple client/server application using RakNet.

I guess that you may be able to find a lot of irc clients and servers on sourceforge if you need more help. Most networking tutorial on the web shows how to write a chating system, so it should not be very difficult to find some server code that may suit your needs.

HTH,
Quote:
Beej's guide to network programming contains the code of servers and clients. It mostly targets unix socket programming (winsock programming is not very different; in fact, it is mostly the same).

programs using sockets in windows need to call WSAStartup() once before any "socket" code, and WSACleanup() after. Apart from that its pretty much the same
Im not interested in some API... not yet at least. If I am to include some network support in my games I would use a API, they can probably code that stuff better than me. :P But now when I learn I want to get down and dirty with the details. Once I got some understanding, I think it will be easier to use the API's effectively. But those two first links seems to contain some info worth reading. Thanks. :)
Read that tutorial from Beej, I tried to compile it but didnt have some of the headers, proably unix headers. Thought I just needed to add the windows specific functions pulpfist stated. But apparently that wasnt the case. Although Beej's tutorial was good, I think I need a windows specific tutorial to complement it.

Anyone got one?
Could you post the errors? As pulpfist said, the only real difference is the startup and closing calls. Just steer clear of the Unix examples that use fork() or exec() or anything like that, and you should be fine. You might need to include "winsock.h" or "winsock2.h".

PS. If you have Python installed, there's a very simple echo server in the docs you can run, giving you something to connect to.
Ok then, Beej's tutorial works towards a simple server that just outputs "Hello World". Heres the server source:

#include <stdio.h>     #include <stdlib.h>     #include <errno.h>     #include <string.h>     #include <sys/types.h> //    #include <netinet/in.h>     #include <winsock.h> //    #include <sys/wait.h>     #define MYPORT 3490    /* the port users will be connecting to */    #define BACKLOG 10     /* how many pending connections queue will hold */    main()    {        int sockfd, new_fd;  /* listen on sock_fd, new connection on new_fd */        struct sockaddr_in my_addr;    /* my address information */        struct sockaddr_in their_addr; /* connector's address information */        int sin_size;        if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {            perror("socket");            exit(1);        }        my_addr.sin_family = AF_INET;         /* host byte order */        my_addr.sin_port = htons(MYPORT);     /* short, network byte order */        my_addr.sin_addr.s_addr = INADDR_ANY; /* auto-fill with my IP */        bzero(&(my_addr.sin_zero), 8);        /* zero the rest of the struct */        if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr))                                                                       == -1) {            perror("bind");            exit(1);        }        if (listen(sockfd, BACKLOG) == -1) {            perror("listen");            exit(1);        }        while(1) {  /* main accept() loop */            sin_size = sizeof(struct sockaddr_in);            if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr,                                                           &sin_size)) == -1) {                perror("accept");                continue;            }            printf("server: got connection from %s\n",                                                inet_ntoa(their_addr.sin_addr));            if (!fork()) { /* this is the child process */                if (send(new_fd, "Hello, world!\n", 14, 0) == -1)                    perror("send");                close(new_fd);                exit(0);            }            close(new_fd);  /* parent doesn't need this */            while(waitpid(-1,NULL,WNOHANG) > 0); /* clean up child processes */        }    }


Ive commented out two headers my compiler didnt like (Microsoft VC++ .NET). And I changed #include <netinet/in.h> to #include <winsock.h>.

After that Im getting errors I really shouldnt try to fix as I yet dont understand the socket concept. Would probably break more than I fixed. :P

Errors:
Compiling...main.cppd:\Documents\CPP\Msn\main.cpp(21) : warning C4244: '=' : conversion from 'SOCKET' to 'int', possible loss of datad:\Documents\CPP\Msn\main.cpp(29) : error C3861: 'bzero': identifier not found, even with argument-dependent lookupd:\Documents\CPP\Msn\main.cpp(45) : warning C4244: '=' : conversion from 'SOCKET' to 'int', possible loss of datad:\Documents\CPP\Msn\main.cpp(51) : error C3861: 'fork': identifier not found, even with argument-dependent lookupd:\Documents\CPP\Msn\main.cpp(54) : error C3861: 'close': identifier not found, even with argument-dependent lookupd:\Documents\CPP\Msn\main.cpp(57) : error C3861: 'close': identifier not found, even with argument-dependent lookupd:\Documents\CPP\Msn\main.cpp(59) : error C2065: 'WNOHANG' : undeclared identifierd:\Documents\CPP\Msn\main.cpp(59) : error C3861: 'waitpid': identifier not found, even with argument-dependent lookupd:\Documents\CPP\Msn\main.cpp(59) : fatal error C1903: unable to recover from previous error(s); stopping compilation


There are mostly "identifier not found" so those should be easy to fix. I thought I somehow had left some code out but that shouldnt be the case. There are no includes that point to stuff he has written, and this is all the code from this chapter.

Besides, I see there are some pesky fork() functions there which I was told to stay away from. Is this tutorial not suited for me? Since its unix based and Im using windows?
Try to include <winsock2.h> instead of winsock

And btw. where is the WSAStartup/WASCleanup ?
you need to use those something like
main(){  WSADATA wsaData;  int err;   short wVersionRequested = MAKEWORD( 2, 2 );   err = WSAStartup( wVersionRequested, &wsaData );  if ( err != 0 ) {    /* Tell the user that we could not find a usable WinSock DLL. */    return;  }  ...  WSACleanup();}


Looks like Beej's tutor uses some UNIX only system calls like fork, and waitpid aswell.

change:
  if (!fork()) { /* this is the child process */    if (send(new_fd, "Hello, world!\n", 14, 0) == -1)      perror("send");      close(new_fd);      exit(0);   }   close(new_fd);  /* parent doesn't need this */   while(waitpid(-1,NULL,WNOHANG) > 0); /* clean up child processes */

to:
  if (send(new_fd, "Hello, world!\n", 14, 0) == -1)      perror("send");  close(new_fd);


EDIT:
AND include <io.h> for the close routine

AND change:
bzero(&(my_addr.sin_zero), 8); /* zero the rest of the struct */

to: memset(&(my_addr.sin_zero), 0, 8); /* zero the rest of the struct */

which in turn requiers you to include <string.h> or something...

[Edited by - pulpfist on November 4, 2005 8:06:11 AM]
Hmmm altough the changes werent complicated, there were quite a few of them. I googled my way to a winsock tutorial instead. And see where it leads, Ill post again if there any more problems. :)
No, no they're fine, just need a little tweaking.

Here's the headers I generally use:
#ifdef _WIN32#include <winsock.h>#define socklen_t int#else#include <fcntl.h>#include <sys/socket.h>#include <netdb.h>#include <sys/types.h>#include <netinet/in.h>#include <unistd.h>#include <sys/time.h>#include <arpa/inet.h>#endif


bzero can be #defined as [or replaced with]:
#define bzero(p, l) memset(p, 0, l)

since it doesn't seem to exist in windows [afaik]

and close is best as closesocket on windows [a simple #ifdef _WIN32 #else]

And pulp fist showed how to eliminate fork.

[edit:
Quote:
Hmmm altough the changes werent complicated, there were quite a few of them. I googled my way to a winsock tutorial instead. And see where it leads, Ill post again if there any more problems. :)


Portability is a virtue in network coding. It's easier to make a few little #ifdefs and tweaks to make BSD style sockets run in windows than try to replicate winsock on another system.]

This topic is closed to new replies.

Advertisement