init project

This commit is contained in:
chenwj113 2022-10-14 11:02:13 +08:00
parent 5cb9f86b2f
commit 2b54085d17
26 changed files with 1080 additions and 0 deletions

1
.gitignore vendored
View File

@ -86,3 +86,4 @@ dkms.conf
*.out *.out
*.app *.app
**/build

10
intro/Makefile Normal file
View File

@ -0,0 +1,10 @@
srcfiles = $(wildcard *.c)
CC = gcc
CFLAGS += -Wall -lunp
objs = $(basename $(srcfiles))
all:
@for obj in $(objs); do \
$(CC) $$obj.c $(CFLAGS) -o build/$$obj; \
done
.PHONY: all

24
intro/byteorder.c Normal file
View File

@ -0,0 +1,24 @@
#include "unp.h"
int main(int argc, char* argv[])
{
union
{
short s;
char c[sizeof(short)];
} un;
un.s = 0x0102;
printf("%s: ", CPU_VENDOR_OS);
size_t size_of_short = sizeof(short);
if(size_of_short == 2) {
if(un.c[0] == 1 && un.c[1] == 2)
printf("big-endian\n");
else if(un.c[0] == 2 && un.c[1] == 1)
printf("little-endian\n");
else
printf("unknown\n");
} else {
printf("sizeof(short) = %ld\n", size_of_short);
}
}

33
intro/daytimetcpcli.c Normal file
View File

@ -0,0 +1,33 @@
#include "unp.h"
int main(int argc, char ** argv)
{
int sockfd, n;
char recvline[MAXLINE + 1];
struct sockaddr_in servaddr;
if(argc != 2)
err_quit("usage: a.out <IPaddress>");
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
err_sys("socket error");
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(10013); // daytime server
if(inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
err_quit("inet_pton error for %s", argv[1]);
if(connect(sockfd, (SA *)&servaddr, sizeof(servaddr)) < 0)
err_sys("connect error");
while((n = read(sockfd, recvline, MAXLINE)) > 0) {
recvline[n] = 0; // null terminate
if(fputs(recvline, stdout) == EOF)
err_sys("fputs error");
}
if(n < 0)
err_sys("read error");
exit(0);
}

33
intro/daytimetcpcliv6.c Normal file
View File

@ -0,0 +1,33 @@
#include "unp.h"
int main(int argc, char ** argv)
{
int sockfd, n;
char recvline[MAXLINE + 1];
struct sockaddr_in6 servaddr;
if(argc != 2)
err_quit("usage: a.out <IPaddress>");
if((sockfd = socket(AF_INET6, SOCK_STREAM, 0)) < 0)
err_sys("socket error");
bzero(&servaddr, sizeof(servaddr));
servaddr.sin6_family = AF_INET6;
servaddr.sin6_port = htons(13); // daytime server
if(inet_pton(AF_INET6, argv[1], &servaddr.sin6_addr) <= 0)
err_quit("inet_pton error for %s", argv[1]);
if(connect(sockfd, (SA *)&servaddr, sizeof(servaddr)) < 0)
err_sys("connect error");
while((n = read(sockfd, recvline, MAXLINE)) > 0) {
recvline[n] = 0; // null terminate
if(fputs(recvline, stdout) == EOF)
err_sys("fputs error");
}
if(n < 0)
err_sys("read error");
exit(0);
}

28
intro/daytimetcpsrv.c Normal file
View File

@ -0,0 +1,28 @@
#include "unp.h"
#include <time.h>
int main(int argc, char *argv[])
{
int listenfd, connfd;
struct sockaddr_in servaddr;
char buff[MAXLINE];
time_t ticks;
listenfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(10013); // daytime server
Bind(listenfd, (SA *)&servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ);
for(;;) {
connfd = Accept(listenfd, (SA *) NULL, NULL);
ticks = time(NULL);
snprintf(buff, sizeof(buff), "Hello, Stupid Bitch ! %.24s\r\n", ctime(&ticks));
Write(connfd, buff, strlen(buff));
Close(connfd);
}
}

32
intro/daytimetcpsrv1.c Normal file
View File

@ -0,0 +1,32 @@
#include "unp.h"
#include <time.h>
int main(int argc, char *argv[])
{
int listenfd, connfd;
struct sockaddr_in servaddr, cliaddr;
socklen_t len;
char buff[MAXLINE];
time_t ticks;
listenfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(10013); // daytime server
Bind(listenfd, (SA *)&servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ);
for(;;) {
len = sizeof(cliaddr);
connfd = Accept(listenfd, (SA *) &cliaddr, &len);
printf("connection from %s, port %d\n",
Inet_ntop(AF_INET, &cliaddr.sin_addr, buff, sizeof(buff)), ntohs(cliaddr.sin_port));
ticks = time(NULL);
snprintf(buff, sizeof(buff), "Hello, Stupid Bitch ! %.24s\r\n", ctime(&ticks));
Write(connfd, buff, strlen(buff));
Close(connfd);
}
}

40
intro/daytimetcpsrv2.c Normal file
View File

@ -0,0 +1,40 @@
#include "unp.h"
#include <time.h>
int main(int argc, char *argv[])
{
int listenfd, connfd;
struct sockaddr_in servaddr, cliaddr;
socklen_t len;
char buff[MAXLINE];
time_t ticks;
pid_t pid;
listenfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(10013); // daytime server
Bind(listenfd, (SA *)&servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ);
for(;;) {
connfd = Accept(listenfd, (SA *) &cliaddr, &len);
if((pid = fork()) == 0) {
len = sizeof(cliaddr);
Close(listenfd);
printf("connection from %s, port %d, pid %d\n",
Inet_ntop(AF_INET, &cliaddr.sin_addr, buff, sizeof(buff)), ntohs(cliaddr.sin_port), getpid());
sleep(5);
printf("after 5 seconds\n");
ticks = time(NULL);
snprintf(buff, sizeof(buff), "Hello, Stupid Bitch ! %.24s\r\n", ctime(&ticks));
Write(connfd, buff, strlen(buff));
Close(connfd);
exit(0);
}
Close(connfd);
}
}

10
select/Makefile Normal file
View File

@ -0,0 +1,10 @@
srcfiles = $(wildcard *.c)
CC = gcc
CFLAGS += -Wall -lunp
objs = $(basename $(srcfiles))
all:
@for obj in $(objs); do \
$(CC) $$obj.c $(CFLAGS) -o build/$$obj; \
done
.PHONY: all

52
select/strcliselect01.c Normal file
View File

@ -0,0 +1,52 @@
#include "unp.h"
void str_cli(FILE *, int);
int main(int argc, char* argv[])
{
int sockfd;
struct sockaddr_in servaddr;
if(argc != 2)
err_quit("usage: tcpcli <IPaddress>");
sockfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
str_cli(stdin, sockfd);
exit(0);
}
void str_cli(FILE *fp, int sockfd)
{
int maxfdp1;
fd_set rset;
char sendline[MAXLINE], recvline[MAXLINE];
FD_ZERO(&rset);
for(;;) {
FD_SET(fileno(fp), &rset);
FD_SET(sockfd, &rset);
maxfdp1 = max(fileno(fp), sockfd) + 1;
Select(maxfdp1, &rset, NULL, NULL, NULL);
if(FD_ISSET(sockfd, &rset)) { // socket is readable
if(Readline(sockfd, recvline, MAXLINE) == 0)
err_quit("str_cli: server terminated prematurely");
Fputs(recvline, stdout);
}
if(FD_ISSET(fileno(fp), &rset)) { // input is readable
if(Fgets(sendline, MAXLINE, fp) == NULL)
return; // all done
Writen(sockfd, sendline, strlen(sendline));
}
}
}

63
select/strcliselect02.c Normal file
View File

@ -0,0 +1,63 @@
#include "unp.h"
void str_cli(FILE *, int);
int main(int argc, char* argv[])
{
int sockfd;
struct sockaddr_in servaddr;
if(argc != 2)
err_quit("usage: tcpcli <IPaddress>");
sockfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
str_cli(stdin, sockfd);
exit(0);
}
void str_cli(FILE *fp, int sockfd)
{
int maxfdp1, stdineof;
fd_set rset;
char buf[MAXLINE];
int n;
stdineof = 0;
FD_ZERO(&rset);
for(;;) {
if(stdineof == 0)
FD_SET(fileno(fp), &rset);
FD_SET(sockfd, &rset);
maxfdp1 = max(fileno(fp), sockfd) + 1;
Select(maxfdp1, &rset, NULL, NULL, NULL);
if(FD_ISSET(sockfd, &rset)) { // socket is readable
if((n = Read(sockfd, buf, MAXLINE)) == 0) {
if (stdineof == 1)
return; // normal termination
else
err_quit("str_cli: server terminated prematurely");
}
Write(fileno(stdout), buf, n);
}
if(FD_ISSET(fileno(fp), &rset)) { // input is readable
if( (n=Read(fileno(fp), buf, MAXLINE)) == 0) {
stdineof = 1;
Shutdown(sockfd, SHUT_WR); // send FIN
FD_CLR(fileno(fp), &rset);
continue;
}
Writen(sockfd, buf, n);
}
}
}

88
select/tcpsrvpoll01.c Normal file
View File

@ -0,0 +1,88 @@
#include "unp.h"
#include <limits.h> // for OPEN_MAX
#ifndef OPEN_MAX
#define OPEN_MAX _SC_OPEN_MAX
#endif
int main(int argc, char *argv[])
{
int listenfd, confd, sockfd, maxi, i;
int nready;
ssize_t n;
char buf[MAXLINE];
socklen_t clilen;
struct pollfd client[OPEN_MAX];
struct sockaddr_in cliaddr, servaddr;
listenfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
Bind(listenfd, (SA *)&servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ);
client[0].fd = listenfd;
client[0].events = POLLIN;
for(i = 1; i < OPEN_MAX; i++)
client[i].fd = -1;
maxi = 0;
for(;;) {
nready = Poll(client, maxi + 1, INFTIM);
if(client[0].revents & POLLIN) { // new client connection
clilen = sizeof(cliaddr);
confd = Accept(listenfd, (SA *) &cliaddr, &clilen);
for ( i = 0; i < OPEN_MAX; i++)
if(client[i].fd < 0) {
client[i].fd = confd; // save descriptor
break;
}
if( i == OPEN_MAX)
err_quit("too many clients");
client[i].events = POLLIN;
if( i > maxi)
maxi = i; // max index in client[] array
if(--nready <= 0)
continue; // no more readable descriptor
}
for(i = 0; i <= maxi; i++) { // check all clients for data
if((sockfd = client[i].fd) < 0)
continue;
if(client[i].revents & (POLLIN | POLLERR)) {
if( (n = Read(sockfd, buf, MAXLINE)) < 0) {
if( errno == ECONNRESET) {
// connection closed by client
Close(sockfd);
client[i].fd = -1;
} else {
err_sys("read error");
}
} else if(n == 0) {
// connection closed by client
Close(sockfd);
client[i].fd = -1;
} else {
Writen(sockfd, buf, n);
}
if(--nready <= 0)
break; // no more readable descriptors
}
}
}
}

78
select/tcpsrvselect01.c Normal file
View File

@ -0,0 +1,78 @@
#include "unp.h"
int main(int argc, char *argv[])
{
int listenfd, confd, sockfd, maxfd, maxi, i;
int nready, client[FD_SETSIZE];
ssize_t n;
fd_set rset, allset;
char buf[MAXLINE];
socklen_t clilen;
struct sockaddr_in cliaddr, servaddr;
listenfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
Bind(listenfd, (SA *)&servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ);
maxfd = listenfd; // initalize
maxi = -1; // index into client[] array
for(i = 0; i<FD_SETSIZE; i++)
client[i] = -1; // -1 indicates available entry
FD_ZERO(&allset);
FD_SET(listenfd, &allset);
for(;;) {
rset = allset; // structure assignment
nready = Select(maxfd+1, &rset, NULL, NULL, NULL);
if(FD_ISSET(listenfd, &rset)) { // new client connection
clilen = sizeof(cliaddr);
confd = Accept(listenfd, (SA *) &cliaddr, &clilen);
for ( i = 0; i < FD_SETSIZE; i++)
if(client[i] < 0) {
client[i] = confd; // save descriptor
break;
}
if( i == FD_SETSIZE)
err_quit("too many clients");
FD_SET(confd, &allset); // add new descriptor to set
if(confd > maxfd)
maxfd = confd; // for select
if( i > maxi)
maxi = i; // max index in client[] array
if(--nready <= 0)
continue; // no more readable descriptor
}
for(i = 0; i <= maxi; i++) { // check all clients for data
if((sockfd = client[i]) < 0)
continue;
if(FD_ISSET(sockfd, &rset)) {
if( (n = Read(sockfd, buf, MAXLINE)) == 0) {
// connection closed by client
Close(sockfd);
FD_CLR(sockfd, &allset);
client[i] = -1;
} else {
Writen(sockfd, buf, n);
}
if(--nready <= 0)
break; // no more readable descriptors
}
}
}
}

10
sockopt/Makefile Normal file
View File

@ -0,0 +1,10 @@
srcfiles = $(wildcard *.c)
CC = gcc
CFLAGS += -Wall -lunp
objs = $(basename $(srcfiles))
all:
@for obj in $(objs); do \
$(CC) $$obj.c $(CFLAGS) -o build/$$obj; \
done
.PHONY: all

121
sockopt/checkopts.c Normal file
View File

@ -0,0 +1,121 @@
#include "unp.h"
#include <netinet/tcp.h>
union val
{
int i_val;
long l_val;
struct linger linger_val;
struct timeval timeval_val;
} val;
static char *sock_str_flag(union val *, int);
static char *sock_str_int(union val *, int);
static char *sock_str_linger(union val *, int);
static char *sock_str_timeval(union val *, int);
static char intres[128];
static char flagres[256];
static char lingerres[128];
static char timevalres[128];
struct sock_opts {
const char *opt_str;
int opt_level;
int opt_name;
char *(*opt_val_str)(union val *, int);
} sock_opts[] = {
{"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, sock_str_flag},
{"SO_DEBUG", SOL_SOCKET, SO_DEBUG, sock_str_flag},
{"SO_DONTROUTE", SOL_SOCKET, SO_DONTROUTE, sock_str_flag},
{"SO_ERROR", SOL_SOCKET, SO_ERROR, sock_str_int },
{"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, sock_str_flag},
{"SO_LINGER", SOL_SOCKET, SO_LINGER, sock_str_linger},
{"SO_OOBINLINE", SOL_SOCKET, SO_OOBINLINE, sock_str_flag},
{"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, sock_str_int },
{"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, sock_str_int },
{"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, sock_str_int },
{"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, sock_str_int },
{"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, sock_str_timeval },
{"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, sock_str_timeval },
{"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, sock_str_flag},
// #ifdef SO_REUSEPORT
// {"SO_REUSEPORT", SOL_SOCKET, SO_REUSEPORT, sock_str_flag},
// #else
// {"SO_REUSEPORT", 0, 0, NULL},
// #endif
{"SO_TYPE", SOL_SOCKET, SO_TYPE, sock_str_int},
// #ifdef SO_USELOOPBACK
// {"SO_USELOOPBACK", SOL_SOCKET, SO_USELOOPBACK, sock_str_flag},
// #else
// {"SO_USELOOPBACK", 0, 0, NULL},
// #endif
};
int main(int argc, char * argv[])
{
int fd;
socklen_t len;
struct sock_opts *ptr;
for( ptr = sock_opts; ptr->opt_str != NULL; ptr++) {
printf("%s: ", ptr->opt_str);
if(ptr->opt_val_str == NULL)
printf("(undefined)\n");
else {
switch (ptr->opt_level)
{
case SOL_SOCKET:
fd = Socket(AF_INET, SOCK_STREAM, 0);
break;
default:
err_quit("Can't create fd for level %d\n", ptr->opt_level);
}
}
len = sizeof(val);
if(getsockopt(fd, ptr->opt_level, ptr->opt_name, &val, &len) == -1) {
err_ret("getsockopt error");
} else {
printf("default = %s\n", (*ptr->opt_val_str)(&val, len));
}
close(fd);
}
}
char *sock_str_flag(union val *ptr, int len)
{
if(len != sizeof(int))
snprintf(flagres, sizeof(flagres), "size(%d) not sizeof(int)", len);
else
snprintf(flagres, sizeof(flagres), "%s", (ptr->i_val == 0)? "off": "on");
return(flagres);
}
char *sock_str_int(union val *ptr, int len)
{
if(len != sizeof(int))
snprintf(intres, sizeof(intres), "size(%d) not sizeof(int)", len);
else
snprintf(intres, sizeof(intres), "%d", ptr->i_val);
return(intres);
}
char *sock_str_linger(union val *ptr, int len)
{
if(len != sizeof(val.linger_val))
snprintf(lingerres, sizeof(lingerres), "size(%d) not sizeof(linger)", len);
else
snprintf(lingerres, sizeof(lingerres), "l_onoff = %d, l_linger = %d", ptr->linger_val.l_onoff, ptr->linger_val.l_linger);
return(lingerres);
}
char *sock_str_timeval(union val *ptr, int len)
{
if(len != sizeof(val.timeval_val))
snprintf(timevalres, sizeof(timevalres), "size(%d) not sizeof(timeval)", len);
else
snprintf(timevalres, sizeof(timevalres), "%ld sec, %ld usec", ptr->timeval_val.tv_sec, ptr->timeval_val.tv_usec);
return(timevalres);
}

10
tcpclisrv/Makefile Normal file
View File

@ -0,0 +1,10 @@
srcfiles = $(wildcard *.c)
CC = gcc
CFLAGS += -Wall -lunp
objs = $(basename $(srcfiles))
all:
@for obj in $(objs); do \
$(CC) $$obj.c $(CFLAGS) -o build/$$obj; \
done
.PHONY: all

39
tcpclisrv/tcpcli01.c Normal file
View File

@ -0,0 +1,39 @@
#include "unp.h"
void str_cli(FILE *, int);
int main(int argc, char* argv[])
{
int sockfd;
struct sockaddr_in servaddr;
if(argc != 2)
err_quit("usage: tcpcli <IPaddress>");
sockfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
str_cli(stdin, sockfd);
exit(0);
}
void str_cli(FILE *fp, int sockfd)
{
char sendline[MAXLINE], recvline[MAXLINE];
while(Fgets(sendline, MAXLINE, fp ) != NULL) {
Writen(sockfd, sendline, strlen(sendline));
if(Readline(sockfd, recvline, MAXLINE) == 0)
err_quit("str_cli: server terminated prematurely");
Fputs(recvline, stdout);
}
}

42
tcpclisrv/tcpcli04.c Normal file
View File

@ -0,0 +1,42 @@
#include "unp.h"
void str_cli(FILE *, int);
int main(int argc, char* argv[])
{
int i, sockfd[5];
struct sockaddr_in servaddr;
if(argc != 2)
err_quit("usage: tcpcli <IPaddress>");
for (i = 0; i < 5; i++){
sockfd[i] = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
Connect(sockfd[i], (SA *) &servaddr, sizeof(servaddr));
}
str_cli(stdin, sockfd[0]);
exit(0);
}
void str_cli(FILE *fp, int sockfd)
{
char sendline[MAXLINE], recvline[MAXLINE];
while(Fgets(sendline, MAXLINE, fp ) != NULL) {
Writen(sockfd, sendline, strlen(sendline));
if(Readline(sockfd, recvline, MAXLINE) == 0)
err_quit("str_cli: server terminated prematurely");
Fputs(recvline, stdout);
}
}

45
tcpclisrv/tcpsrv01.c Normal file
View File

@ -0,0 +1,45 @@
#include "unp.h"
void str_echo(int);
int main(int argc, char *argv[])
{
int listenfd, confd;
pid_t childpid;
socklen_t clilen;
struct sockaddr_in cliaddr, servaddr;
listenfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
Bind(listenfd, (SA *)&servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ);
for(;;) {
clilen = sizeof(cliaddr);
confd = Accept(listenfd, (SA *) &cliaddr, &clilen);
if((childpid = Fork()) == 0) { // child process
Close(listenfd); // close listening socket
str_echo(confd);
exit(0);
}
Close(confd); // parent close connected socket
}
}
void str_echo(int sockfd)
{
ssize_t n;
char buf[MAXLINE];
again:
while((n = read(sockfd, buf, MAXLINE)) > 0)
Writen(sockfd, buf, n);
if(n < 0 && errno == EINTR)
goto again;
else if (n < 0)
err_sys("str echo: read error");
}

58
tcpclisrv/tcpsrv02.c Normal file
View File

@ -0,0 +1,58 @@
#include "unp.h"
void str_echo(int);
void sig_chld(int);
int main(int argc, char *argv[])
{
int listenfd, confd;
pid_t childpid;
socklen_t clilen;
struct sockaddr_in cliaddr, servaddr;
listenfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
Bind(listenfd, (SA *)&servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ);
Signal(SIGCHLD, sig_chld);
for(;;) {
clilen = sizeof(cliaddr);
confd = Accept(listenfd, (SA *) &cliaddr, &clilen);
if((childpid = Fork()) == 0) { // child process
Close(listenfd); // close listening socket
str_echo(confd);
exit(0);
}
Close(confd); // parent close connected socket
}
}
void str_echo(int sockfd)
{
ssize_t n;
char buf[MAXLINE];
again:
while((n = read(sockfd, buf, MAXLINE)) > 0)
Writen(sockfd, buf, n);
if(n < 0 && errno == EINTR)
goto again;
else if (n < 0)
err_sys("str echo: read error");
}
void sig_chld(int signo)
{
pid_t pid;
int stat;
pid = wait(&stat);
printf("child %d terminated\n", pid);
return;
}

63
tcpclisrv/tcpsrv03.c Normal file
View File

@ -0,0 +1,63 @@
#include "unp.h"
void str_echo(int);
void sig_chld(int);
int main(int argc, char *argv[])
{
int listenfd, confd;
pid_t childpid;
socklen_t clilen;
struct sockaddr_in cliaddr, servaddr;
listenfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
Bind(listenfd, (SA *)&servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ);
Signal(SIGCHLD, sig_chld);
for(;;) {
clilen = sizeof(cliaddr);
if((confd = accept(listenfd, (SA *) &cliaddr, &clilen))< 0 ) {
if (errno == EINTR)
continue; // back to for()
else
err_sys("accept error");
}
if((childpid = Fork()) == 0) { // child process
Close(listenfd); // close listening socket
str_echo(confd);
exit(0);
}
Close(confd); // parent close connected socket
}
}
void str_echo(int sockfd)
{
ssize_t n;
char buf[MAXLINE];
again:
while((n = read(sockfd, buf, MAXLINE)) > 0)
Writen(sockfd, buf, n);
if(n < 0 && errno == EINTR)
goto again;
else if (n < 0)
err_sys("str echo: read error");
}
void sig_chld(int signo)
{
pid_t pid;
int stat;
pid = wait(&stat);
printf("child %d terminated\n", pid);
return;
}

65
tcpclisrv/tcpsrv04.c Normal file
View File

@ -0,0 +1,65 @@
#include "unp.h"
void str_echo(int);
void sig_chld(int);
int main(int argc, char *argv[])
{
int listenfd, confd;
pid_t childpid;
socklen_t clilen;
struct sockaddr_in cliaddr, servaddr;
listenfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
Bind(listenfd, (SA *)&servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ);
Signal(SIGCHLD, sig_chld); // must call waitpid()
for(;;) {
clilen = sizeof(cliaddr);
if((confd = accept(listenfd, (SA *) &cliaddr, &clilen))< 0 ) {
if (errno == EINTR)
continue; // back to for()
else
err_sys("accept error");
}
if((childpid = Fork()) == 0) { // child process
Close(listenfd); // close listening socket
str_echo(confd);
exit(0);
}
Close(confd); // parent close connected socket
}
}
void str_echo(int sockfd)
{
ssize_t n;
char buf[MAXLINE];
again:
while((n = read(sockfd, buf, MAXLINE)) > 0)
Writen(sockfd, buf, n);
if(n < 0 && errno == EINTR)
goto again;
else if (n < 0)
err_sys("str echo: read error");
}
void sig_chld(int signo)
{
pid_t pid;
int stat;
while ((pid = waitpid(-1, &stat, WNOHANG)) > 0)
{
printf("child %d terminated\n", pid);
}
return;
}

10
udpclisrv/Makefile Normal file
View File

@ -0,0 +1,10 @@
srcfiles = $(wildcard *.c)
CC = gcc
CFLAGS += -Wall -lunp
objs = $(basename $(srcfiles))
all:
@for obj in $(objs); do \
$(CC) $$obj.c $(CFLAGS) -o build/$$obj; \
done
.PHONY: all

38
udpclisrv/udpcli01.c Normal file
View File

@ -0,0 +1,38 @@
#include "unp.h"
void dg_cli(FILE *, int, const SA*, socklen_t);
int main(int argc, char* argv[])
{
int sockfd;
struct sockaddr_in servaddr;
if(argc != 2)
err_quit("usage: udpcli <IPaddress>");
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
dg_cli(stdin, sockfd, (SA *)&servaddr, sizeof(servaddr));
exit(0);
}
void dg_cli(FILE *fp, int sockfd, const SA* pservaddr, socklen_t servlen)
{
int n;
char sendline[MAXLINE], recvline[MAXLINE];
while (Fgets(sendline, MAXLINE, fp) !=NULL) {
Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);
n = Recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL);
recvline[n] = 0; // null terminate
Fputs(recvline, stdout);
}
}

49
udpclisrv/udpcli02.c Normal file
View File

@ -0,0 +1,49 @@
#include "unp.h"
void dg_cli(FILE *, int, const SA*, socklen_t);
int main(int argc, char* argv[])
{
int sockfd;
struct sockaddr_in servaddr;
if(argc != 2)
err_quit("usage: udpcli <IPaddress>");
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
// servaddr.sin_port = htons(SERV_PORT);
servaddr.sin_port = htons(7);
Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
dg_cli(stdin, sockfd, (SA *)&servaddr, sizeof(servaddr));
exit(0);
}
void dg_cli(FILE *fp, int sockfd, const SA* pservaddr, socklen_t servlen)
{
int n;
char sendline[MAXLINE], recvline[MAXLINE];
socklen_t len;
struct sockaddr *preply_addr;
preply_addr = Malloc(servlen);
while (Fgets(sendline, MAXLINE, fp) !=NULL) {
Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);
len = servlen;
n = Recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len);
if(len != servlen || memcmp(pservaddr, preply_addr, len) != 0) {
printf("reply from %s (ignored)\n", Sock_ntop(preply_addr, len));
continue;
}
recvline[n] = 0; // null terminate
Fputs(recvline, stdout);
}
}

38
udpclisrv/udpsrv01.c Normal file
View File

@ -0,0 +1,38 @@
#include "unp.h"
void dg_echo(int, SA*, socklen_t);
int main(int argc, char* argv[])
{
int sockfd;
struct sockaddr_in servaddr, cliaddr;
sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
Bind(sockfd, (SA *)&servaddr, sizeof(servaddr));
dg_echo(sockfd, (SA *)&cliaddr, sizeof(cliaddr));
}
void dg_echo(int sockfd, SA *pcliaddr, socklen_t clien)
{
int n;
socklen_t len;
char msg[MAXLINE];
char res[MAXLINE];
char greeting[] = "This is from server: ";
for(;;) {
len = clien;
n = Recvfrom(sockfd, msg, MAXLINE, 0, pcliaddr, &len);
strcpy(res, "");
strncat(res, greeting, strlen(greeting));
strncat(res, msg, n);
Sendto(sockfd, res, strlen(res), 0, pcliaddr, len);
}
}