oob_send.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define BUG_SIZE 30
void error_handling(char* message);
int main(int argc, char* argv[]) {
if (argc != 3) {
printf("param is lack\n");
exit(-1);
}
int sock;
struct sockaddr_in recv_addr;
sock = socket(PF_INET, SOCK_STREAM, 0);
memset(&recv_addr, 0, sizeof(recv_addr));
recv_addr.sin_family = AF_INET;
recv_addr.sin_addr.s_addr = inet_addr(argv[1]);
recv_addr.sin_port = htons(atoi(argv[2]));
if (connect(sock, (struct sockaddr*)&recv_addr, sizeof(recv_addr)) == -1) {
printf("connect() error\n");
exit(-1);
}
write(sock, "123", strlen("123"));
send(sock, "4", strlen("1"), MSG_OOB);
write(sock, "567", strlen("567"));
send(sock, "890", strlen("890"), MSG_OOB);
close(sock);
return 0;
}
oob_recv.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#define BUF_SIZE 30
void error_handler(char* message);
void urg_handler(int signo);
int accept_sock;
int recv_sock;
int main(int argc, char* argv[]) {
struct sockaddr_in recv_addr, serv_addr;
socklen_t serv_len;
struct sigaction act;
char buf[BUF_SIZE];
if (argc != 2) {
printf("Usage: %s <port>\n", argv[0]);
exit(-1);
}
act.sa_handler = urg_handler;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
accept_sock = socket(PF_INET, SOCK_STREAM, 0);
memset(&recv_addr, 0, sizeof(recv_addr));
recv_addr.sin_family = AF_INET;
recv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
recv_addr.sin_port = htons(atoi(argv[1]));
if (bind(accept_sock, (struct sockaddr*)&recv_addr, sizeof(recv_addr)) == -1) {
error_handler("bind() error");
}
listen(accept_sock, 5);
serv_len = sizeof(recv_addr);
recv_sock = accept(accept_sock, (struct sockaddr*)&serv_addr, &serv_len);
//指定信号由那个进程处理,因为一个套接字可以被多个进程使用
fcntl(recv_sock, F_SETOWN, getpid());
int state = sigaction(SIGURG, &act, 0);
int str_len = 0;
while ((str_len = recv(recv_sock, buf, sizeof(buf), 0)) != 0) {
if (str_len == -1) {
continue;
}
buf[str_len] = 0;
puts(buf);
}
close(recv_sock);
close(accept_sock);
return 0;
}
void urg_handler(int signo) {
int str_len = 0;
char buf[BUF_SIZE];
str_len = recv(recv_sock, buf, sizeof(buf) - 1, MSG_OOB);
buf[str_len] = 0;
printf("Urgent message: %s \n", buf);
}
void error_handler(char* message) {
fputs(message, stderr);
fputc('\n', stderr);
exit(-1);
}
MSG_OOB模式并不会加快传输速度,而且每次MSG_OOB只能接收1个字节,紧急消息只是督促接收方尽快处理,所以后续的数据需要使用常规的方式读取