APPENDIX E

Appendix E contains the code listing for the TCP-based file transmission programs mentioned in Chapter 2.

// *********************************

// * TCP-based File Transfer Server

// * Filename: TCPserver.c

// *********************************

#include <stdio.h>

#include <windows.h>

#include <io.h>

#include <fcntl.h>

#include <sys/stat.h>

#include <sys/types.h>

#include <errno.h>

#include <time.h>

#define MYPORT 8888

#define MPEG_FILE "test.mpg"

#define BLOCK 1024

// PROTOTYPE DECLARATIONS

int net_init();

void net_close(int sd);

void do_accept(SOCKET sd);

void render_MPEG(SOCKET sd);

void main() {

int sd;

if ( (sd = net_init()) < 0 )

exit(0);

do_accept(sd);

}

// FUNCTION net_init initializes TCP connections, etc

int net_init() {

int sd;

struct sockaddr_in myaddr;

WSADATA WsaData;

WORD wVersionRequested;

int err;

wVersionRequested = MAKEWORD(1, 1);

err = WSAStartup(wVersionRequested, &WsaData);

if (err != 0) {

printf("Couldn't find WinSock 1.1 DLL\n");

return -1;

}

if ( (sd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET ) {

printf("socket err %d\n", WSAGetLastError());

return -1;

}

ZeroMemory((char *)&myaddr, sizeof(myaddr));

myaddr.sin_family = AF_INET;

myaddr.sin_port = htons(MYPORT);

myaddr.sin_addr.s_addr = htonl(INADDR_ANY);

if ( bind(sd, (struct sockaddr *)&myaddr, sizeof(myaddr)) == SOCKET_ERROR ) {

printf("bind %d\n", WSAGetLastError());

return -1;

}

if ( listen(sd, 5) == SOCKET_ERROR ) {

printf("listen %d\n", WSAGetLastError());

return -1;

}

return sd;

}

//FUNCTION closes TCP client connection

void net_close(int sd) {

closesocket(sd);

}

// FUNCTION do_accept handles incoming clients

void do_accept(SOCKET sd) {

int newsd, len;

int count = 0;

struct sockaddr_in clientaddr;

clock_t start_t, stop_t;

double duration;

len = sizeof(clientaddr);

while (1) {

if ( (newsd = accept(sd, (struct sockaddr *)&clientaddr, &len)) == INVALID_SOCKET ) {

printf("accept err %d\n", WSAGetLastError());

break;

}

start_t = clock();

render_MPEG(newsd);

stop_t = clock();

duration = (double)(stop_t - start_t)/CLOCKS_PER_SEC;

printf("Time taken is %2.2f seconds\n", duration);

net_close(newsd);

}

}

void render_MPEG(SOCKET sd) {

int fd, readn=0, b=0, sendn=0, c, total=0;

char *buffer;

struct _stat file_stat;

// do _stat to check for file size

if ( _stat(MPEG_FILE, &file_stat) < 0 ) {

if (errno == ENOENT) {

printf("File %s could not be found\n", MPEG_FILE);

return;

}

else {

printf("_stat error unknown\n");

return;

}

}

// open the MPEG file

if ( (fd = _open(MPEG_FILE, _O_RDONLY|_O_BINARY)) == -1 ) {

printf("_open error %d on file %s\n", errno, MPEG_FILE);

}

else {

// read MPEG file

// then send MPEG file, block by block

buffer = (char *)malloc(BLOCK);

while (file_stat.st_size - b != 0) {

// risk the chances that _read() might read less than st_size

if ( (readn = _read(fd, buffer, BLOCK)) < 0 ) {

printf("_read error %d\n", errno);

break;

}

b += readn;

if ( (sendn = send(sd, buffer, readn, 0)) == SOCKET_ERROR ) {

printf("1 send error %d\n", WSAGetLastError());

break;

}

total += sendn;

// just being careful in case socket's send() does not transmit

// all of the buffer at one time

while (sendn < readn) {

c = send(sd, &buffer[sendn], readn-sendn, 0);

if (c == SOCKET_ERROR) {

printf("2 send error %d\n", WSAGetLastError());

return;

}

else {

sendn += c;

total += sendn;

}

}

} // end while

printf("Done! Sent %d bytes\n", total);

_close(fd);

net_close(sd);

} // end if else

}

// *********************************

// * TCP-based File Transfer Client

// * Filename: TCPclient.c

// *********************************

#include <windows.h>

#include <stdio.h>

#include <io.h>

#include <fcntl.h>

#include <sys/stat.h>

#include <time.h>

// GLOBALS

#define SERVERPORT 8888

#define BLOCK 1024

// PROTOTYPE DECLARATIONS

int net_init();

void net_close(int sd);

void get_MPEG(SOCKET sd, char *filename, int filesize);

char HOSTADDR[20];

void main(int argc, char *argv[]) {

SOCKET sd;

char mpegfile[20];

clock_t start_t, stop_t;

double duration;

if (argc < 2) {

printf("usage: TCPclient [IPaddress]\n");

exit(0);

}

strcpy(HOSTADDR,argv[1]);

printf("Let's boogie!\n");

printf("Enter a filename for the MPEG that you are to receive\n");

printf("It must end with \".mpg\": ");

scanf("%s", mpegfile);

printf("%s\n", mpegfile);

if ( (sd = net_init()) < 0 ) {

printf("net_init failure\n");

exit(0);

}

start_t = clock();

get_MPEG(sd, mpegfile, 0);

stop_t = clock();

duration = (double)(stop_t - start_t)/CLOCKS_PER_SEC;

printf("Time taken is %2.2f seconds\n", duration);

net_close(sd);

}

int net_init() {

int sd;

struct sockaddr_in addr;

WORD wVersionRequested;

WSADATA WsaData;

int err;

wVersionRequested = MAKEWORD(1, 1);

err = WSAStartup(wVersionRequested, &WsaData);

if (err != 0) {

printf("Couldn't find WinSock 1.1 DLL\n");

return -1;

}

if ( (sd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {

printf("socket error %d\n", WSAGetLastError());

return -1;

}

ZeroMemory((char *) &addr, sizeof(addr));

addr.sin_family = AF_INET;

addr.sin_port = htons(SERVERPORT);

addr.sin_addr.s_addr = inet_addr(HOSTADDR);

if (bind(sd, (struct sockaddr *)&addr, sizeof(addr)) < SOCKET_ERROR) {

printf("bind %d\n", WSAGetLastError());

return -1;

}

if (connect(sd, (struct sockaddr *)&addr, sizeof(addr)) == SOCKET_ERROR) {

printf("connect %d\n", WSAGetLastError());

return -1;

}

return sd;

}

void net_close(int sd) {

closesocket(sd);

if (WSACleanup() == SOCKET_ERROR)

printf("WSACleanup err %d\n", WSAGetLastError());

}

// FUNCTION get_MPEG reads data recursively from server

// and writes to a specified file

// + assumes that server will disconnect after it has completed its transmission

void get_MPEG(SOCKET sd, char *filename, int filesize) {

int recvn;

char *buffer;

int fd, writen;

buffer = (char *)malloc(BLOCK);

if ( (recvn=recv(sd, buffer, BLOCK, 0)) == SOCKET_ERROR ) {

if (WSAGetLastError() == WSAECONNRESET)

printf("Connection reset by host\n");

else printf("recv err %d\n", WSAGetLastError());

net_close(sd);

return;

}

filesize += recvn;

if (recvn == 0)

printf("Bleep!!\n");

if ( (fd = _open(filename,

_O_WRONLY|_O_CREAT|_O_APPEND|_O_BINARY,

_S_IREAD|_S_IWRITE)) != -1 ) {

if ( (writen = _write(fd, buffer, recvn)) < 0 )

printf("write error %d\n", errno);

else if (writen == 0) {

printf("Last recvd: %d\n", recvn);

printf("Recvd total of %d bytes\n", filesize);

_close(fd);

return;

}

else if (writen != recvn) {

printf("recvd %d, but wrote %d !\n", recvn, writen);

_close(fd);

return;

}

_close(fd);

}

get_MPEG(sd, filename, filesize);

}