Что-то я сегодня добрый. Ну да ладно:/* -*- C -*- */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#ifdef WIN32
# include <winsock2.h>
# include <windows.h>
#define sleep(n) SleepEx((n)*1000, FALSE);
typedef int ssize_t;
#else
# include <sys/types.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <arpa/inet.h>
# include <netdb.h>
# include <unistd.h>
# include <strings.h>
#define SOCKET int
#define INVALID_SOCKET (-1)
#define closesocket close
extern int h_errno;
#endif
#define BUF_SIZE 32768
static int do_resolve_addr(const char* host, struct sockaddr_in* addr_in)
{
struct hostent *hp = NULL;
do {
errno = 0;
hp = gethostbyname(host);
} while ( hp==NULL && (h_errno==TRY_AGAIN || errno==EINTR) );
if ( hp==NULL )
return -1;
memcpy(&addr_in->sin_addr, *(hp->h_addr_list),
sizeof(addr_in->sin_addr.s_addr));
return 0;
}
static int do_make_address(const char* addr, struct sockaddr_in* addr_in)
{
char *new_host, *new_port;
new_host = strdup(addr);
new_port = strstr(new_host, ":");
if ( new_port )
{
*new_port = '\0';
new_port++;
}
else
new_port = "9999";
addr_in->sin_family = AF_INET;
addr_in->sin_port = htons((unsigned short)atoi(new_port));
addr_in->sin_addr.s_addr = inet_addr(new_host);
if ( addr_in->sin_addr.s_addr == -1)
if ( do_resolve_addr(new_host, addr_in) < 0 ) {
fprintf(stderr, "netstream: cannot resolve address: %s\n", strerror(errno));
free(new_host);
return -1;
}
free(new_host);
return 0;
}
/* ------------------------------------------------------------ */
static int do_send(const char* addr, FILE* f)
{
char buf[BUF_SIZE];
struct sockaddr_in addr_in;
SOCKET sock, cnc;
int nbytes;
if ( do_make_address(addr, &addr_in) == -1 )
return 1;
sock = socket(AF_INET, SOCK_STREAM, 0);
if ( sock==-1 ) {
fprintf(stderr, "netstream: cannot create socket: %s\n", strerror(errno));
return 1;
}
if ( bind(sock, (struct sockaddr *)&addr_in, sizeof(addr_in)) == -1 ) {
fprintf(stderr, "netstream: cannot bind socket: %s\n", strerror(errno));
shutdown(sock, 2);
closesocket(sock);
return 1;
}
if ( listen(sock, 1) == -1 ) {
fprintf(stderr, "netstream: cannot listen: %s\n", strerror(errno));
shutdown(sock, 2);
closesocket(sock);
return 1;
}
do {
cnc = accept(sock, NULL, NULL);
if ( cnc<0 )
sleep(1);
} while (cnc<0);
shutdown(sock, 2);
closesocket(sock); sock = -1;
while ( !ferror(f) && !feof(f) ) {
nbytes = (int)fread(buf, 1, sizeof(buf), f);
if ( nbytes<1 )
continue;
if ( send(cnc, buf, nbytes, 0) == -1 ) {
fprintf(stderr, "netstream: cannot send: %s\n", strerror(errno));
shutdown(cnc, 2);
closesocket(cnc);
return 2;
}
}
if ( ferror(f) ) {
fprintf(stderr, "netstream: file read error: %s\n", strerror(errno));
return 2;
}
shutdown(cnc, 2);
closesocket(cnc);
return 0;
}
/* ------------------------------------------------------------ */
static int do_recv(const char* addr, FILE* f)
{
char buf[BUF_SIZE];
struct sockaddr_in addr_in;
SOCKET sock;
ssize_t nbytes;
if ( do_make_address(addr, &addr_in) == -1 )
return 1;
sock = socket(AF_INET, SOCK_STREAM, 0);
if ( sock==INVALID_SOCKET ) {
fprintf(stderr, "netstream: cannot create socket: %s\n", strerror(errno));
return 1;
}
if (connect(sock, (struct sockaddr*)&addr_in, sizeof(addr_in)) == -1) {
fprintf(stderr, "netstream: unable to connect: %s\n", strerror(errno));
shutdown(sock, 2);
closesocket(sock);
return 1;
}
for (;;) {
nbytes = recv(sock, buf, sizeof(buf), 0);
if ( nbytes==0 )
break;
if ( nbytes < 0 ) {
fprintf(stderr, "netstream: unable to recv: %s\n", strerror(errno));
shutdown(sock, 2);
closesocket(sock);
return 2;
}
if (fwrite(buf, 1, nbytes, f) != (size_t)nbytes) {
fprintf(stderr, "netstream: file write failed: %s\n", strerror(errno));
shutdown(sock, 2);
closesocket(sock);
return 2;
}
}
shutdown(sock, 2);
closesocket(sock);
return 0;
}
/* ------------------------------------------------------------ */
static void usage_and_die()
{
fprintf(stderr, "USAGE:\n\tnetstream {send|receive} address [filename]\n");
exit(3);
}
int main(int argc, char* argv[])
{
int ret = 0;
FILE* f = NULL;
#ifdef WIN32
WORD wVersionRequested;
WSADATA data;
wVersionRequested = MAKEWORD(1, 1);
WSAStartup(wVersionRequested, &data);
#endif
if ( argc!=3 && argc!=4 )
usage_and_die();
switch ( *argv[1] ) {
case 's': case 'S':
f = stdin;
if ( argc==4 )
f = fopen(argv[3], "rb");
break;
case 'r': case 'R':
f = stdout;
if ( argc==4 )
f = fopen(argv[3], "wb");
break;
default:
usage_and_die();
}
if ( argc==4 && f==NULL ) {
fprintf(stderr, "netstream: cannot open '%s': %s\n", argv[3], strerror(errno));
return 2;
}
switch ( *argv[1] ) {
case 's': case 'S':
ret = do_send(argv[2], f);
break;
case 'r': case 'R':
ret = do_recv(argv[2], f);
break;
}
if ( f!=stdin || f!=stdout )
fclose(f);
return ret;
}
/* End Of File */