Skip to content

Commit

Permalink
added multiple-connection functions
Browse files Browse the repository at this point in the history
  • Loading branch information
H2CO3 committed Jan 23, 2012
1 parent 1fa55c7 commit de064f0
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 4 deletions.
23 changes: 23 additions & 0 deletions README
Expand Up @@ -44,6 +44,29 @@ This function tries to connect to a server at <hostname>, _already listening_ on
return 0;
}

To write a server that accepts multiple connections, do like this:

#include "tcpconnect.h"

int main(int argc, char **argv) {
int sockfd = tcpconnect_start_multiple(argv[1]); /* ./server 5555 */
int acceptsock = 0;
while (1) {
acceptsock = tcpconnect_accept_single(sockfd);
/* create a new thread or fork() and pass the new thread/process
the returned file descriptor
Example:
pthread_t tid;
int *sockptr = malloc(sizeof (int));
*sockptr = accpetsock;
pthread_create(&tid, NULL, server_thread_function, sockptr);
*/
}
return 0;
}



An asynchronously working wrapper Objective-C class, TCPHelper is built around these functions. It uses a delegation system to notify
about its state changes, corresponding to certain network actions. The method names of this class are meant to be self-explanatory, so I've included some example code in Server.m and Client.m. (You can build them using `make sample'.)

Expand Down
22 changes: 18 additions & 4 deletions tcpconnect.c
Expand Up @@ -49,7 +49,7 @@ int tcpconnect_start_client(const char *hostname, const char *port) {
return sockfd;
}

int tcpconnect_start_server(const char *port) {
int tcpconnect_start_multiple(const char *port) {
int status = 0; /* return status of the inet/socket functions */
struct addrinfo *servinfo = NULL;
struct addrinfo hints;
Expand Down Expand Up @@ -102,14 +102,28 @@ int tcpconnect_start_server(const char *port) {
return -1;
}

return sockfd;
}

int tcpconnect_accept_single(int stubfd) {
struct sockaddr_storage client_addr; /* client's address info */
socklen_t clientaddr_size = sizeof(client_addr);
int newsockfd = accept(sockfd, (struct sockaddr *)&client_addr, &clientaddr_size);
close(sockfd);
int newsockfd = accept(stubfd, (struct sockaddr *)&client_addr, &clientaddr_size);
if (newsockfd < 0) {
return -1;
}

return newsockfd;
}

int tcpconnect_start_server(const char *port) {
int stubfd = tcpconnect_start_multiple(port);
if (stubfd < 0) {
return -1;
}
int sockfd = tcpconnect_accept_single(stubfd);
close(stubfd);
if (sockfd < 0) {
return -1;
}
return sockfd;
}
36 changes: 36 additions & 0 deletions tcpconnect.h
Expand Up @@ -18,6 +18,27 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <pthread.h>


/*
Function type to be invoked in separate threads whenever tcpconnect_persistent_server() encounters
a new incoming connection. It will be supplied
a pointer to a socket file descriptor.
This pointer is to be free()'d after use.
*/

typedef void (*tcpconnect_server_fn_t)(int *fdptr);

/*
Callback function used by tcpconnect_persistent_server() to notify about creation of new server threads.
This function must not perform heavy computation or otherwise time consuming operations.
tid is a pthread_t containing info about the newly spawned thread.
sockfd must not be read from nor written to, it's there only in order the callback to know
which socket descriptor belongs to which thread.
*/

typedef void (*tcpconnect_callback_fn_t)(pthread_t tid, int sockfd);

/*
Returns a socket file descriptor,
Expand All @@ -43,5 +64,20 @@ int tcpconnect_start_client(const char *hostname, const char *port);

int tcpconnect_start_server(const char *port);

/*
Returns a file descriptor, which can be supplied to tcpconnect_accept_single in order to retrieve
a read()able-write()able socket file descriptor.
*/

int tcpconnect_start_multiple(const char *port);

/*
Takes a socket file descriptor returned by tcpconnect_start_multiple(). This blocks until a
client connects to the other end of the socket.
Returns a readable-writable socket file descriptor on success or negative on error.
*/

int tcpconnect_accept_single(int stubfd);

#endif /* !__TCPCONNECT_H__ */

0 comments on commit de064f0

Please sign in to comment.