Skip to content

Commit

Permalink
books: boooks examples, Beejs Guide ex-s
Browse files Browse the repository at this point in the history
  • Loading branch information
sumkincpp committed Mar 28, 2021
1 parent 678531f commit 2c743c4
Show file tree
Hide file tree
Showing 19 changed files with 2,471 additions and 0 deletions.
17 changes: 17 additions & 0 deletions books/bgnet_examples/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
TARGETS=broadcaster client getip ghbn ieee754 listener pack pack2 \
poll pollserver select selectserver server showip talker telnot

CC=gcc
CCOPTS=-Wall -Wextra

.PHONY: all clean pristine

all: $(TARGETS)

clean:
rm -f $(TARGETS)

pristine: clean

%: %.c
$(CC) $(CCOPTS) -o $@ $<
4 changes: 4 additions & 0 deletions books/bgnet_examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Beej's Guide to Network Programming Examples

Type `make` to build.

67 changes: 67 additions & 0 deletions books/bgnet_examples/broadcaster.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
** broadcaster.c -- a datagram "client" like talker.c, except
** this one can broadcast
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

#define SERVERPORT 4950 // the port users will be connecting to

int main(int argc, char *argv[])
{
int sockfd;
struct sockaddr_in their_addr; // connector's address information
struct hostent *he;
int numbytes;
int broadcast = 1;
//char broadcast = '1'; // if that doesn't work, try this

if (argc != 3) {
fprintf(stderr,"usage: broadcaster hostname message\n");
exit(1);
}

if ((he=gethostbyname(argv[1])) == NULL) { // get the host info
perror("gethostbyname");
exit(1);
}

if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
perror("socket");
exit(1);
}

// this call is what allows broadcast packets to be sent:
if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &broadcast,
sizeof broadcast) == -1) {
perror("setsockopt (SO_BROADCAST)");
exit(1);
}

their_addr.sin_family = AF_INET; // host byte order
their_addr.sin_port = htons(SERVERPORT); // short, network byte order
their_addr.sin_addr = *((struct in_addr *)he->h_addr);
memset(their_addr.sin_zero, '\0', sizeof their_addr.sin_zero);

if ((numbytes=sendto(sockfd, argv[2], strlen(argv[2]), 0,
(struct sockaddr *)&their_addr, sizeof their_addr)) == -1) {
perror("sendto");
exit(1);
}

printf("sent %d bytes to %s\n", numbytes,
inet_ntoa(their_addr.sin_addr));

close(sockfd);

return 0;
}
94 changes: 94 additions & 0 deletions books/bgnet_examples/client.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
** client.c -- a stream socket client demo
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>

#include <arpa/inet.h>

#define PORT "3490" // the port client will be connecting to

#define MAXDATASIZE 100 // max number of bytes we can get at once

// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{
if (sa->sa_family == AF_INET) {
return &(((struct sockaddr_in*)sa)->sin_addr);
}

return &(((struct sockaddr_in6*)sa)->sin6_addr);
}

int main(int argc, char *argv[])
{
int sockfd, numbytes;
char buf[MAXDATASIZE];
struct addrinfo hints, *servinfo, *p;
int rv;
char s[INET6_ADDRSTRLEN];

if (argc != 2) {
fprintf(stderr,"usage: client hostname\n");
exit(1);
}

memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;

if ((rv = getaddrinfo(argv[1], PORT, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}

// loop through all the results and connect to the first we can
for(p = servinfo; p != NULL; p = p->ai_next) {
if ((sockfd = socket(p->ai_family, p->ai_socktype,
p->ai_protocol)) == -1) {
perror("client: socket");
continue;
}

if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
perror("client: connect");
close(sockfd);
continue;
}

break;
}

if (p == NULL) {
fprintf(stderr, "client: failed to connect\n");
return 2;
}

inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr),
s, sizeof s);
printf("client: connecting to %s\n", s);

freeaddrinfo(servinfo); // all done with this structure

if ((numbytes = recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) {
perror("recv");
exit(1);
}

buf[numbytes] = '\0';

printf("client: received '%s'\n",buf);

close(sockfd);

return 0;
}

32 changes: 32 additions & 0 deletions books/bgnet_examples/getip.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
** getip.c -- a hostname lookup demo
*/

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main(int argc, char *argv[])
{
struct hostent *h;

if (argc != 2) { // error check the command line
fprintf(stderr,"usage: getip address\n");
exit(1);
}

if ((h=gethostbyname(argv[1])) == NULL) { // get the host info
herror("gethostbyname");
exit(1);
}

printf("Host name : %s\n", h->h_name);
printf("IP Address : %s\n", inet_ntoa(*((struct in_addr *)h->h_addr)));

return 0;
}
42 changes: 42 additions & 0 deletions books/bgnet_examples/ghbn.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
** ghbn.c -- a hostname lookup demo
**
** THIS IS A DEPRECATED METHOD OF GETTING HOST NAMES
** use getaddrinfo() instead.
*/

#include <stdio.h>
#include <errno.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main(int argc, char *argv[])
{
int i;
struct hostent *he;
struct in_addr **addr_list;

if (argc != 2) { // error check the command line
fprintf(stderr,"usage: ghbn hostname\n");
return 1;
}

if ((he = gethostbyname(argv[1])) == NULL) { // get the host info
herror("gethostbyname");
return 2;
}

// print information about this host:
printf("Official name is: %s\n", he->h_name);
printf(" IP addresses: ");
addr_list = (struct in_addr **)he->h_addr_list;
for(i = 0; addr_list[i] != NULL; i++) {
printf("%s ", inet_ntoa(*addr_list[i]));
}
printf("\n");

return 0;
}
88 changes: 88 additions & 0 deletions books/bgnet_examples/ieee754.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

#define pack754_32(f) (pack754((f), 32, 8))
#define pack754_64(f) (pack754((f), 64, 11))
#define unpack754_32(i) (unpack754((i), 32, 8))
#define unpack754_64(i) (unpack754((i), 64, 11))

uint64_t pack754(long double f, unsigned bits, unsigned expbits)
{
long double fnorm;
int shift;
long long sign, exp, significand;
unsigned significandbits = bits - expbits - 1; // -1 for sign bit

if (f == 0.0) return 0; // get this special case out of the way

// check sign and begin normalization
if (f < 0) { sign = 1; fnorm = -f; }
else { sign = 0; fnorm = f; }

// get the normalized form of f and track the exponent
shift = 0;
while(fnorm >= 2.0) { fnorm /= 2.0; shift++; }
while(fnorm < 1.0) { fnorm *= 2.0; shift--; }
fnorm = fnorm - 1.0;

// calculate the binary form (non-float) of the significand data
significand = fnorm * ((1LL<<significandbits) + 0.5f);

// get the biased exponent
exp = shift + ((1<<(expbits-1)) - 1); // shift + bias

// return the final answer
return (sign<<(bits-1)) | (exp<<(bits-expbits-1)) | significand;
}

long double unpack754(uint64_t i, unsigned bits, unsigned expbits)
{
long double result;
long long shift;
unsigned bias;
unsigned significandbits = bits - expbits - 1; // -1 for sign bit

if (i == 0) return 0.0;

// pull the significand
result = (i&((1LL<<significandbits)-1)); // mask
result /= (1LL<<significandbits); // convert back to float
result += 1.0f; // add the one back on

// deal with the exponent
bias = (1<<(expbits-1)) - 1;
shift = ((i>>significandbits)&((1LL<<expbits)-1)) - bias;
while(shift > 0) { result *= 2.0; shift--; }
while(shift < 0) { result /= 2.0; shift++; }

// sign it
result *= (i>>(bits-1))&1? -1.0: 1.0;

return result;
}

int main(void)
{
float f = 3.1415926, f2;
double d = 3.14159265358979323, d2;
uint32_t fi;
uint64_t di;

fi = pack754_32(f);
f2 = unpack754_32(fi);

di = pack754_64(d);
d2 = unpack754_64(di);

printf("float before : %.7f\n", f);
printf("float encoded: 0x%08" PRIx32 "\n", fi);
printf("float after : %.7f\n\n", f2);

printf("double before : %.20lf\n", d);
printf("double encoded: 0x%016" PRIx64 "\n", di);
printf("double after : %.20lf\n", d2);

return 0;
}

Loading

0 comments on commit 2c743c4

Please sign in to comment.