第二十四章 带外数据:
#include <sys/socket.h>
int sockatmark(int sockfd);
have oob mark return 1, have not oob mark return 0, error return -1
示例:
#include <sys/ioctl.h>
int
sockatmark(int fd)
{
int flag;
if (ioctl(fd, SIOCATMARK, &flag) == -1) {
return(-1);
}
return(flag != 0);
}
#include "err_exit.h"
#include "tcp_connect.h"
int
main(int argc, char ** argv)
{
int sockfd;
if (argc != 3) {
printf("usage: tcpsend01 <host> <port#>\n");
exit(1);
}
sockfd = tcp_connect(argv[1], argv[2]);
if (write(sockfd, "123", 3) != 3) {
err_exit("write error");
}
printf("wrote 3 bytes of normal data\n");
sleep(1);
if (send(sockfd, "4", 1, MSG_OOB) != 1) {
err_exit("send error");
}
printf("wrote 1 byte of OOB data\n");
sleep(1);
if (write(sockfd, "56", 2) != 2) {
err_exit("write error");
}
printf("wrote 2 bytes of normal data\n");
sleep(1);
if (send(sockfd, "7", 1, MSG_OOB) != 1) {
err_exit("send error");
}
printf("wrote 1 byte of OOB data\n");
sleep(1);
if (write(sockfd, "89", 2) != 2) {
err_exit("write error");
}
printf("wrote 2 bytes of normal data\n");
sleep(1);
exit(0);
}
#include <fcntl.h>
#include "err_exit.h"
#include "my_signal.h"
#include "tcp_listen.h"
int listenfd;
int connfd;
void
sig_urg(int signo)
{
int n;
char buff[100];
printf("SIGURG received\n");
if ((n = recv(connfd, buff, sizeof(buff)-1, MSG_OOB)) < 0) {
err_exit("recv error");
}
buff[n] = 0; /* null terminate */
printf("read %d OOB byte: %s\n", n, buff);
}
int
main(int argc, char ** argv)
{
int n;
char buff[100];
if (argc == 2) {
listenfd = tcp_listen(NULL, argv[1], NULL);
}
else if (argc == 3) {
listenfd = tcp_listen(argv[1], argv[2], NULL);
}
else {
printf("usage: tcprecv01 [ <host> ] <port#>\n");
}
if ((connfd = accept(listenfd, NULL, NULL)) == -1) {
err_exit("accept error");
}
if (my_signal(SIGURG, sig_urg) == SIG_ERR) {
err_exit("my_signal error");
}
if (fcntl(connfd, F_SETOWN, getpid()) == -1) {
err_exit("fcntl error");
}
for ( ; ; ) {
if ((n = read(connfd, buff, sizeof(buff)-1)) < 0) {
err_exit("read error");
}
else if (n == 0) {
printf("received EOF\n");
exit(0);
}
buff[n] = 0; /* null terminate */
printf("read %d bytes: %s\n", n, buff);
}
}
#include "err_exit.h"
#include "tcp_listen.h"
int
main(int argc, char ** argv)
{
int listenfd;
int connfd;
int n;
int justreadoob = 0;
char buff[100];
fd_set rset;
fd_set xset;
if (argc == 2) {
listenfd = tcp_listen(NULL, argv[1], NULL);
}
else if (argc == 3) {
listenfd = tcp_listen(argv[1], argv[2], NULL);
}
else {
printf("usage: tcprecv02 [ <host> ] <port#>\n");
exit(1);
}
if ((connfd = accept(listenfd, NULL, NULL)) == -1) {
err_exit("accept error");
}
FD_ZERO(&rset);
FD_ZERO(&xset);
for ( ; ; ) {
FD_SET(connfd, &rset);
if (justreadoob == 0) {
FD_SET(connfd, &xset);
}
if (select(connfd + 1, &rset, NULL, &xset, NULL) == -1) {
err_exit("select error");
}
if (FD_ISSET(connfd, &xset)) {
if ((n = recv(connfd, buff, sizeof(buff)-1, MSG_OOB)) < 0) {
err_exit("recv error");
}
buff[n] = 0; /* null terminate */
printf("read %d OOB byte: %s\n", n, buff);
justreadoob = 1;
FD_CLR(connfd, &xset);
}
if (FD_ISSET(connfd, &rset)) {
if ((n = read(connfd, buff, sizeof(buff)-1)) < 0) {
err_exit("read error");
}
else if (n == 0) {
printf("received EOF\n");
exit(0);
}
buff[n] = 0; /* null terminate */
printf("read %d bytes: %s\n", n, buff);
justreadoob = 0;
}
}
}
#include "err_exit.h"
#include "tcp_listen.h"
int
main(int argc, char ** argv)
{
int listenfd;
int connfd;
int n;
int on = 1;
char buff[100];
if (argc == 2) {
listenfd = tcp_listen(NULL, argv[1], NULL);
}
else if (argc == 3) {
listenfd = tcp_listen(argv[1], argv[2], NULL);
}
else {
printf("usage: tcprecv02 [ <host> ] <port#>\n");
exit(1);
}
if (setsockopt(listenfd, SOL_SOCKET, SO_OOBINLINE, &on, sizeof(on)) == -1) {
err_exit("setsockopt error");
}
if ((connfd = accept(listenfd, NULL, NULL)) == -1) {
err_exit("accept error");
}
sleep(5);
for ( ; ; ) {
if ((n = sockatmark(connfd)) == -1) {
err_exit("sockatmark error");
}
else if (n == 1) {
printf("at OOB mark\n");
}
if ((n = read(connfd, buff, sizeof(buff)-1)) < 0) {
err_exit("read error");
}
else if (n == 0) {
printf("received EOF\n");
exit(0);
}
buff[n] = 0; /* null terminate */
printf("read %d bytes: %s\n", n, buff);
}
}
#include "err_exit.h"
#include "tcp_connect.h"
int
main(int argc, char ** argv)
{
int sockfd;
if (argc != 3) {
printf("usage: tcpsend01 <host> <port#>\n");
exit(1);
}
sockfd = tcp_connect(argv[1], argv[2]);
if (write(sockfd, "123", 3) != 3) {
err_exit("write error");
}
printf("wrote 3 bytes of normal data\n");
if (send(sockfd, "4", 1, MSG_OOB) != 1) {
err_exit("send error");
}
printf("wrote 1 byte of OOB data\n");
if (write(sockfd, "5", 1) != 1) {
err_exit("write error");
}
printf("wrote 1 bytes of normal data\n");
exit(0);
}
#include "err_exit.h"
#include "tcp_connect.h"
int
main(int argc, char ** argv)
{
int sockfd;
if (argc != 3) {
printf("usage: tcpsend01 <host> <port#>\n");
exit(1);
}
sockfd = tcp_connect(argv[1], argv[2]);
if (write(sockfd, "123", 3) != 3) {
err_exit("write error");
}
printf("wrote 3 bytes of normal data\n");
sleep(1);
if (send(sockfd, "4", 1, MSG_OOB) != 1) {
err_exit("send error");
}
printf("wrote 1 byte of OOB data\n");
sleep(1);
if (write(sockfd, "5", 1) != 1) {
err_exit("write error");
}
printf("wrote 1 bytes of normal data\n");
sleep(1);
if (send(sockfd, "6", 1, MSG_OOB) != 1) {
err_exit("send error");
}
printf("wrote 1 byte of OOB data\n");
sleep(1);
if (write(sockfd, "7", 1) != 1) {
err_exit("write error");
}
printf("wrote 1 bytes of normal data\n");
sleep(1);
exit(0);
}
#include <fcntl.h>
#include "err_exit.h"
#include "my_signal.h"
#include "tcp_listen.h"
int listenfd;
int connfd;
void
sig_urg(int signo)
{
int n;
char buff[2048];
printf("SIGURG received\n");
if ((n = recv(connfd, buff, sizeof(buff)-1, MSG_OOB)) < 0) {
err_exit("recv error");
}
buff[n] = 0; /* null terminate */
printf("read %d OOB byte: %s\n", n, buff);
}
int
main(int argc, char ** argv)
{
int size = 4096;
if (argc == 2) {
listenfd = tcp_listen(NULL, argv[1], NULL);
}
else if (argc == 3) {
listenfd = tcp_listen(argv[1], argv[2], NULL);
}
else {
printf("usage: tcprecv01 [ <host> ] <port#>\n");
}
if (setsockopt(listenfd, SOL_SOCKET, SO_RCVBUF, &size,
sizeof(size)) == -1) {
err_exit("setsockopt error");
}
if ((connfd = accept(listenfd, NULL, NULL)) == -1) {
err_exit("accept error");
}
if (my_signal(SIGURG, sig_urg) == SIG_ERR) {
err_exit("my_signal error");
}
if (fcntl(connfd, F_SETOWN, getpid()) == -1) {
err_exit("fcntl error");
}
for ( ; ; ) {
pause();
}
}
#include "err_exit.h"
#include "tcp_connect.h"
int
main(int argc, char ** argv)
{
int sockfd;
int size;
char buff[16384];
if (argc != 3) {
printf("usage: tcpsend01 <host> <port#>\n");
exit(1);
}
sockfd = tcp_connect(argv[1], argv[2]);
size = 32768;
if (setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)) == -1) {
err_exit("setsockopt error");
}
if (write(sockfd, buff, 16384) != 16384) {
err_exit("write error");
}
printf("wrote 16384 bytes of normal data\n");
sleep(5);
if (send(sockfd, "a", 1, MSG_OOB) != 1) {
err_exit("send error");
}
printf("wrote 1 byte of OOB data\n");
if (write(sockfd, buff, 1024) != 1024) {
err_exit("write error");
}
printf("wrote 1024 bytes of normal data\n");
exit(0);
}
#include <fcntl.h>
#include <sys/socket.h>
#include "err_exit.h"
#include "my_signal.h"
static int servfd;
static int nsec; /* seconds betweeen each alarm */
static int maxnprobes; /* probes w/no response before quit */
static int nprobes; /* probes since last server response */
void
sig_urg(int signo)
{
int n;
char c;
if ((n = recv(servfd, &c, 1, MSG_OOB)) < 0) {
if (errno != EWOULDBLOCK) {
err_exit("recv error");
}
}
nprobes = 0; /* reset counter */
return; /* may interrupt client code */
}
void
sig_alrm(int signo)
{
if (++nprobes > maxnprobes) {
fprintf(stderr, "server is unreachable\n");
exit(0);
}
if (send(servfd, "1", 1, MSG_OOB) != 1) {
err_exit("send error");
}
alarm(nsec);
return; /* may interrupt client code */
}
void
heartbeat_cli(int servfd_arg, int nsec_arg, int maxnprobes_arg)
{
servfd = servfd_arg; /* set globals for signal handlers */
if ((nsec = nsec_arg) < 1) {
nsec = 1;
}
if ((maxnprobes = maxnprobes_arg) < nsec) {
maxnprobes = nsec;
}
nprobes = 0;
if (my_signal(SIGURG, sig_urg) == SIG_ERR) {
err_exit("my_signal error");
}
if (fcntl(servfd, F_SETOWN, getpid()) == -1) {
err_exit("fcntl error");
}
if (my_signal(SIGALRM, sig_alrm) == SIG_ERR) {
err_exit("my_signal error");
}
alarm(nsec);
}
#include <fcntl.h>
#include <sys/socket.h>
#include "err_exit.h"
#include "my_signal.h"
static int servfd;
static int nsec; /* seconds between each alarm */
static int maxnalarms; /* alarms w/no client probe before quit */
static int nprobes; /* alarms since last client probe */
void
sig_urg(int signo)
{
int n;
char c;
if ((n = recv(servfd, &c, 1, MSG_OOB)) < 0) {
if (errno != EWOULDBLOCK) {
err_exit("recv error");
}
}
if (send(servfd, &c, 1, MSG_OOB) != 1) { /* echo back out-of-band byte */
err_exit("send error");
}
nprobes = 0; /* reset counter */
return; /* may interrupt server code */
}
void
sig_alrm(int signo)
{
if (++nprobes > maxnalarms) {
printf("no probes from client\n");
exit(0);
}
alarm(nsec);
return; /* may interrupt server code */
}
void
heartbeat_serv(int servfd_arg, int nsec_arg, int maxnalarms_arg)
{
servfd = servfd_arg; /* set globals for signal handlers */
if ((nsec = nsec_arg) < 1) {
nsec = 1;
}
if ((maxnalarms = maxnalarms_arg) < nsec) {
maxnalarms = nsec;
}
nprobes = 0;
if (my_signal(SIGURG, sig_urg) == SIG_ERR) {
err_exit("my_signal error");
}
if (fcntl(servfd, F_SETOWN, getpid()) == -1) {
err_exit("fcntl error");
}
if (my_signal(SIGALRM, sig_alrm) == SIG_ERR) {
err_exit("my_signal error");
}
alarm(nsec);
}