Skip to content

Commit a325c1c

Browse files
committed
add sample code of beej's guide of networking programming
1 parent 7a298c5 commit a325c1c

19 files changed

+2471
-0
lines changed

bgnet_examples/Makefile

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
TARGETS=broadcaster client getip ghbn ieee754 listener pack pack2 \
2+
poll pollserver select selectserver server showip talker telnot
3+
4+
CC=gcc
5+
CCOPTS=-Wall -Wextra
6+
7+
.PHONY: all clean pristine
8+
9+
all: $(TARGETS)
10+
11+
clean:
12+
rm -f $(TARGETS)
13+
14+
pristine: clean
15+
16+
%: %.c
17+
$(CC) $(CCOPTS) -o $@ $<

bgnet_examples/README.md

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Beej's Guide to Network Programming Examples
2+
3+
Type `make` to build.
4+

bgnet_examples/broadcaster.c

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
** broadcaster.c -- a datagram "client" like talker.c, except
3+
** this one can broadcast
4+
*/
5+
6+
#include <stdio.h>
7+
#include <stdlib.h>
8+
#include <unistd.h>
9+
#include <errno.h>
10+
#include <string.h>
11+
#include <sys/types.h>
12+
#include <sys/socket.h>
13+
#include <netinet/in.h>
14+
#include <arpa/inet.h>
15+
#include <netdb.h>
16+
17+
#define SERVERPORT 4950 // the port users will be connecting to
18+
19+
int main(int argc, char *argv[])
20+
{
21+
int sockfd;
22+
struct sockaddr_in their_addr; // connector's address information
23+
struct hostent *he;
24+
int numbytes;
25+
int broadcast = 1;
26+
//char broadcast = '1'; // if that doesn't work, try this
27+
28+
if (argc != 3) {
29+
fprintf(stderr,"usage: broadcaster hostname message\n");
30+
exit(1);
31+
}
32+
33+
if ((he=gethostbyname(argv[1])) == NULL) { // get the host info
34+
perror("gethostbyname");
35+
exit(1);
36+
}
37+
38+
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
39+
perror("socket");
40+
exit(1);
41+
}
42+
43+
// this call is what allows broadcast packets to be sent:
44+
if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &broadcast,
45+
sizeof broadcast) == -1) {
46+
perror("setsockopt (SO_BROADCAST)");
47+
exit(1);
48+
}
49+
50+
their_addr.sin_family = AF_INET; // host byte order
51+
their_addr.sin_port = htons(SERVERPORT); // short, network byte order
52+
their_addr.sin_addr = *((struct in_addr *)he->h_addr);
53+
memset(their_addr.sin_zero, '\0', sizeof their_addr.sin_zero);
54+
55+
if ((numbytes=sendto(sockfd, argv[2], strlen(argv[2]), 0,
56+
(struct sockaddr *)&their_addr, sizeof their_addr)) == -1) {
57+
perror("sendto");
58+
exit(1);
59+
}
60+
61+
printf("sent %d bytes to %s\n", numbytes,
62+
inet_ntoa(their_addr.sin_addr));
63+
64+
close(sockfd);
65+
66+
return 0;
67+
}

bgnet_examples/client.c

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
** client.c -- a stream socket client demo
3+
*/
4+
5+
#include <stdio.h>
6+
#include <stdlib.h>
7+
#include <unistd.h>
8+
#include <errno.h>
9+
#include <string.h>
10+
#include <netdb.h>
11+
#include <sys/types.h>
12+
#include <netinet/in.h>
13+
#include <sys/socket.h>
14+
15+
#include <arpa/inet.h>
16+
17+
#define PORT "3490" // the port client will be connecting to
18+
19+
#define MAXDATASIZE 100 // max number of bytes we can get at once
20+
21+
// get sockaddr, IPv4 or IPv6:
22+
void *get_in_addr(struct sockaddr *sa)
23+
{
24+
if (sa->sa_family == AF_INET) {
25+
return &(((struct sockaddr_in*)sa)->sin_addr);
26+
}
27+
28+
return &(((struct sockaddr_in6*)sa)->sin6_addr);
29+
}
30+
31+
int main(int argc, char *argv[])
32+
{
33+
int sockfd, numbytes;
34+
char buf[MAXDATASIZE];
35+
struct addrinfo hints, *servinfo, *p;
36+
int rv;
37+
char s[INET6_ADDRSTRLEN];
38+
39+
if (argc != 2) {
40+
fprintf(stderr,"usage: client hostname\n");
41+
exit(1);
42+
}
43+
44+
memset(&hints, 0, sizeof hints);
45+
hints.ai_family = AF_UNSPEC;
46+
hints.ai_socktype = SOCK_STREAM;
47+
48+
if ((rv = getaddrinfo(argv[1], PORT, &hints, &servinfo)) != 0) {
49+
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
50+
return 1;
51+
}
52+
53+
// loop through all the results and connect to the first we can
54+
for(p = servinfo; p != NULL; p = p->ai_next) {
55+
if ((sockfd = socket(p->ai_family, p->ai_socktype,
56+
p->ai_protocol)) == -1) {
57+
perror("client: socket");
58+
continue;
59+
}
60+
61+
if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
62+
perror("client: connect");
63+
close(sockfd);
64+
continue;
65+
}
66+
67+
break;
68+
}
69+
70+
if (p == NULL) {
71+
fprintf(stderr, "client: failed to connect\n");
72+
return 2;
73+
}
74+
75+
inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr),
76+
s, sizeof s);
77+
printf("client: connecting to %s\n", s);
78+
79+
freeaddrinfo(servinfo); // all done with this structure
80+
81+
if ((numbytes = recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) {
82+
perror("recv");
83+
exit(1);
84+
}
85+
86+
buf[numbytes] = '\0';
87+
88+
printf("client: received '%s'\n",buf);
89+
90+
close(sockfd);
91+
92+
return 0;
93+
}
94+

bgnet_examples/getip.c

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
** getip.c -- a hostname lookup demo
3+
*/
4+
5+
#include <stdio.h>
6+
#include <stdlib.h>
7+
#include <errno.h>
8+
#include <netdb.h>
9+
#include <sys/types.h>
10+
#include <sys/socket.h>
11+
#include <netinet/in.h>
12+
#include <arpa/inet.h>
13+
14+
int main(int argc, char *argv[])
15+
{
16+
struct hostent *h;
17+
18+
if (argc != 2) { // error check the command line
19+
fprintf(stderr,"usage: getip address\n");
20+
exit(1);
21+
}
22+
23+
if ((h=gethostbyname(argv[1])) == NULL) { // get the host info
24+
herror("gethostbyname");
25+
exit(1);
26+
}
27+
28+
printf("Host name : %s\n", h->h_name);
29+
printf("IP Address : %s\n", inet_ntoa(*((struct in_addr *)h->h_addr)));
30+
31+
return 0;
32+
}

bgnet_examples/ghbn.c

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
** ghbn.c -- a hostname lookup demo
3+
**
4+
** THIS IS A DEPRECATED METHOD OF GETTING HOST NAMES
5+
** use getaddrinfo() instead.
6+
*/
7+
8+
#include <stdio.h>
9+
#include <errno.h>
10+
#include <netdb.h>
11+
#include <sys/types.h>
12+
#include <sys/socket.h>
13+
#include <netinet/in.h>
14+
#include <arpa/inet.h>
15+
16+
int main(int argc, char *argv[])
17+
{
18+
int i;
19+
struct hostent *he;
20+
struct in_addr **addr_list;
21+
22+
if (argc != 2) { // error check the command line
23+
fprintf(stderr,"usage: ghbn hostname\n");
24+
return 1;
25+
}
26+
27+
if ((he = gethostbyname(argv[1])) == NULL) { // get the host info
28+
herror("gethostbyname");
29+
return 2;
30+
}
31+
32+
// print information about this host:
33+
printf("Official name is: %s\n", he->h_name);
34+
printf(" IP addresses: ");
35+
addr_list = (struct in_addr **)he->h_addr_list;
36+
for(i = 0; addr_list[i] != NULL; i++) {
37+
printf("%s ", inet_ntoa(*addr_list[i]));
38+
}
39+
printf("\n");
40+
41+
return 0;
42+
}

bgnet_examples/ieee754.c

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#include <stdio.h>
2+
#include <stdint.h>
3+
#include <inttypes.h>
4+
5+
#define pack754_32(f) (pack754((f), 32, 8))
6+
#define pack754_64(f) (pack754((f), 64, 11))
7+
#define unpack754_32(i) (unpack754((i), 32, 8))
8+
#define unpack754_64(i) (unpack754((i), 64, 11))
9+
10+
uint64_t pack754(long double f, unsigned bits, unsigned expbits)
11+
{
12+
long double fnorm;
13+
int shift;
14+
long long sign, exp, significand;
15+
unsigned significandbits = bits - expbits - 1; // -1 for sign bit
16+
17+
if (f == 0.0) return 0; // get this special case out of the way
18+
19+
// check sign and begin normalization
20+
if (f < 0) { sign = 1; fnorm = -f; }
21+
else { sign = 0; fnorm = f; }
22+
23+
// get the normalized form of f and track the exponent
24+
shift = 0;
25+
while(fnorm >= 2.0) { fnorm /= 2.0; shift++; }
26+
while(fnorm < 1.0) { fnorm *= 2.0; shift--; }
27+
fnorm = fnorm - 1.0;
28+
29+
// calculate the binary form (non-float) of the significand data
30+
significand = fnorm * ((1LL<<significandbits) + 0.5f);
31+
32+
// get the biased exponent
33+
exp = shift + ((1<<(expbits-1)) - 1); // shift + bias
34+
35+
// return the final answer
36+
return (sign<<(bits-1)) | (exp<<(bits-expbits-1)) | significand;
37+
}
38+
39+
long double unpack754(uint64_t i, unsigned bits, unsigned expbits)
40+
{
41+
long double result;
42+
long long shift;
43+
unsigned bias;
44+
unsigned significandbits = bits - expbits - 1; // -1 for sign bit
45+
46+
if (i == 0) return 0.0;
47+
48+
// pull the significand
49+
result = (i&((1LL<<significandbits)-1)); // mask
50+
result /= (1LL<<significandbits); // convert back to float
51+
result += 1.0f; // add the one back on
52+
53+
// deal with the exponent
54+
bias = (1<<(expbits-1)) - 1;
55+
shift = ((i>>significandbits)&((1LL<<expbits)-1)) - bias;
56+
while(shift > 0) { result *= 2.0; shift--; }
57+
while(shift < 0) { result /= 2.0; shift++; }
58+
59+
// sign it
60+
result *= (i>>(bits-1))&1? -1.0: 1.0;
61+
62+
return result;
63+
}
64+
65+
int main(void)
66+
{
67+
float f = 3.1415926, f2;
68+
double d = 3.14159265358979323, d2;
69+
uint32_t fi;
70+
uint64_t di;
71+
72+
fi = pack754_32(f);
73+
f2 = unpack754_32(fi);
74+
75+
di = pack754_64(d);
76+
d2 = unpack754_64(di);
77+
78+
printf("float before : %.7f\n", f);
79+
printf("float encoded: 0x%08" PRIx32 "\n", fi);
80+
printf("float after : %.7f\n\n", f2);
81+
82+
printf("double before : %.20lf\n", d);
83+
printf("double encoded: 0x%016" PRIx64 "\n", di);
84+
printf("double after : %.20lf\n", d2);
85+
86+
return 0;
87+
}
88+

0 commit comments

Comments
 (0)