User Tools

Site Tools


Message protocol prototype

msg.h
/*
 * Author, Copyright: Oleg Borodin <onborodin@gmail.com>
 */
 
#ifndef MSG_H_IUYTR
#define MSG_H_IUYTR
 
#include <stdio.h>
#include <sys/endian.h>
#include <string.h>
 
typedef struct msg_hdr {
    uint16_t version;
    uint32_t id;
    uint16_t type;
    uint64_t csize;
    uint16_t pnumber;
    uint16_t pcount;
    uint64_t psize;
    uint64_t poffset;
} msg_hdr_t;
 
typedef struct msg {
    msg_hdr_t header;
    void* content;
} msg_t;
 
void msg_hdr_encode (msg_hdr_t* net, msg_hdr_t* host) {
    net->id = htobe32(host->id);
    net->version = htobe16(host->version);
    net->type = htobe16(host->type);
    net->csize = htobe64(host->csize);
    net->pnumber = htobe16(host->pnumber);
    net->pcount = htobe16(host->pcount);
    net->psize = htobe16(host->psize);
    net->poffset = htobe16(host->poffset);
}
 
void msg_hdr_decode (msg_hdr_t* host, msg_hdr_t* net) {
    host->id = be32toh(net->id);
    host->version = be16toh(net->version);
    host->type = be16toh(net->type);
    host->csize = be64toh(net->csize);
    host->pnumber = be16toh(net->pnumber);
    host->pcount = be16toh(net->pcount);
    host->psize = be16toh(net->psize);
    host->poffset = be16toh(net->poffset);
}
 
#define MSG_VER1 1
 
void msg_init(msg_t* m) {
    memset(m, 0, sizeof(msg_t));
    m->header.version = (MSG_VER1 | 0xFE00);
}
 
void msg_set_size(msg_t* m, uint64_t size) {
    m->header.csize = size;
}
 
uint64_t msg_get_size(msg_t* m) {
    return m->header.csize;
}
 
#endif

server

msg-srv.c
/*
 * Author, Copyright: Oleg Borodin <onborodin@gmail.com>
 */
 
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
 
#include <pthread.h>
#include <sys/event.h>
 
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <err.h>
 
#include <sys/endian.h>
#include "msg.h"
 
int socket_create(int port, int backlog) {
    int sock;
    if((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
        fprintf(stderr, "cannot create socket, exit\n");
        exit(1);
    }
    int optval;
    optval = 1;
    if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0) {
        fprintf(stderr, "cannot set socket option, exit\n");
        exit(1);
    }
 
    struct sockaddr addr;
    struct sockaddr_in* paddr = (struct sockaddr_in*)&addr;
    paddr->sin_family = AF_INET;
    paddr->sin_addr.s_addr = INADDR_ANY;
    paddr->sin_port = htons(port);
    paddr->sin_len = sizeof(struct sockaddr_in);
 
    if (bind(sock, (struct sockaddr*)paddr, paddr->sin_len) < 0) {
        fprintf(stderr, "cannot bind socket, exit\n");
        exit(1);
    }
    if (listen(sock, backlog) < 0) {
        fprintf(stderr, "cannot listen socket, exit\n");
        exit(1);
    }
    return sock;
}
 
 
 
int main(int argc, char **argv) {
 
    int sock = socket_create(1024, 4096);
 
    while (1) {
        int newsock = 0;
        if ((newsock = accept(sock, NULL, 0)) > 3) {
 
            struct timeval tv;
            tv.tv_sec = 3;
            tv.tv_usec = 0;
            if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(struct timeval)) < 0) {
                fprintf(stderr, "cannot set socket option, exit\n");
                exit(1);
            }
            const int bsize = 1024;
            char buffer[bsize];
            int rv = read(newsock, buffer, sizeof(msg_hdr_t));
            if (rv == sizeof(msg_hdr_t)) {
                fprintf(stderr, "receive header:\n");
 
                msg_hdr_t msgh;
                memcpy(&msgh, buffer, sizeof(msg_hdr_t));
                msg_hdr_t h;
                msg_hdr_decode(&h, &msgh);
                fprintf(stderr, "size: %ld\n", h.csize);
 
                if ((rv = read(newsock, buffer, h.csize)) == h.csize) {
                    buffer[h.csize + 1] = 0;
                    fprintf(stderr, "content: %s\n", buffer);
                }
            }
            close(newsock);
        }
    }
    close(sock);
    return 0;
}

client

msg-client.c
/*
 * Author, Copyright: Oleg Borodin <onborodin@gmail.com>
 */
 
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
 
#include <pthread.h>
#include <sys/event.h>
 
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <err.h>
 
#include <netinet/ip.h>
#include <netdb.h>
 
 
#include <sys/endian.h>
#include "msg.h"
 
int sock_connect(char* hostname, const int port) {
 
    int sock;
    if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
        return -1;
    }
 
    struct addrinfo hints;
    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;
 
    struct addrinfo* result = NULL;
 
    int retval;
    if ((retval = getaddrinfo(hostname, NULL, &hints, &result)) != 0) {
        return -1;
    }
 
    struct sockaddr_in* sockaddr = NULL;
    for (struct addrinfo* ptr = result; ptr != NULL; ptr = ptr->ai_next) {
        switch (ptr->ai_family) {
            case AF_INET:
                sockaddr = (struct sockaddr_in*)ptr->ai_addr;
                break;
            default:
                break;
        }
        if (sockaddr != NULL) {
            break;
        }
    }
 
    struct sockaddr addr;
    memset(&addr, 0, sizeof(struct sockaddr));
    memcpy(&addr, sockaddr, sizeof(struct sockaddr_in));
    freeaddrinfo(result);
 
    struct sockaddr_in* paddr = (struct sockaddr_in*)&addr;
    paddr->sin_family = AF_INET;
    paddr->sin_port = htons(port);
    paddr->sin_len = sizeof(struct sockaddr_in);
 
    if (connect(sock, (struct sockaddr*)paddr, paddr->sin_len) < 0) {
        return -1;
    }
    return sock;
}
 
int main(int argc, char **argv) {
    int sock = sock_connect("localhost", 1024);
 
    char buffer[1024];
    memset(buffer, 'z', 1024);
 
    //char data[] = "hello, world!";
 
    msg_t m;
    msg_init(&m);
    if (argc > 1) {
        m.content = argv[1];
        m.header.csize = strlen(argv[1]);
    }
 
    msg_hdr_t n;
    msg_hdr_encode(&n, &(m.header));
    write(sock, &n, sizeof(msg_hdr_t));
    write(sock, m.content, m.header.csize);
 
    //sleep(1);
    close(sock);
    return 0;
}

out

client

$ ./msg-client hello,world

server

$ ./msg-srv 
receive header:
size: 11
content: hello,world

First PagePrevious PageBack to overviewNext PageLast Page