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);
}