-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
books: boooks examples, Beejs Guide ex-s
- Loading branch information
Showing
19 changed files
with
2,471 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 $@ $< |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
|
Oops, something went wrong.