Let's straight to the point.
Simply to make tcp segmented traffic, we need to turn off Nagle's algorithm. We can accomplish this with TCP_NODELAY option. I needed one for my test, but I couldn't find an example.
Since it is not that hard, I just wrote one. Don't expect too much in this example, however. I just needed this real quick, and wrote very sloppy. Here it comes:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0)
#define MAXDATASIZE 8192
#define SERVER_ADDR "172.16.136.147"
#define SERVER_PORT 80
#define PAYLOAD "GET /index.html"
#define CHUNK 2 // chunk size. 2 byte segment for each.
int main()
{
int sockfd, numbytes;
char buf[MAXDATASIZE] = {0, };
int optval;
struct sockaddr_in srv;
sockfd = socket(PF_INET, SOCK_STREAM, 0);
if (sockfd == -1)
handle_error("socket failed");
optval = 1;
if ( 0 > setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval))
handle_error("sockopt, REUSEADDR");
optval = 1;
if ( 0 > setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (char *) &optval, sizeof optval))
handle_error("sockopt, NO NAGLE");
memset(&srv, '\0', sizeof srv);
srv.sin_family = AF_INET;
srv.sin_port = htons(SERVER_PORT);
if ( 0 > inet_pton(AF_INET, SERVER_ADDR, &srv.sin_addr))
handle_error("lookup fail");
// CONNECT!
if ( 0 > connect(sockfd, (struct sockaddr *)&srv, sizeof srv))
handle_error("connect error");
// Lazy: I'm not handling buffer overflow.
strcpy(buf, PAYLOAD);
int i;
char sbuf[ CHUNK ];
for (i=0; i<strlen(PAYLOAD); i += CHUNK) {
strncpy(sbuf, buf+i, CHUNK);
write(sockfd, sbuf, CHUNK);
usleep(100000); // give time to clear the system call.
}
write(sockfd, "\n\n", 2);
if ((numbytes = recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1)
handle_error("recv");
buf[numbytes] = '\0';
printf("client: received '%s'\n",buf);
close(sockfd);
return 0;
}
Thursday, January 8, 2009
Subscribe to:
Posts (Atom)