参考资料:<<Linux网络编程.pdf>>page119-205
代码本来是全照书上抄的,后来发现编译不成功,所以就稍微改了下。下面是我修改后的代码:
server.c
// OOB套接字传输服务端(Server.c) #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/wait.h> #include <netinet/in.h> #include <fcntl.h> #define MYPORT 4000 #define BACKLOG 10 int new_fd; void sig_urg(int signo) { int n; char buf[100]; printf("SIGURG received\n"); n = recv(new_fd, buf, sizeof(buf)-1, MSG_OOB); buf[n] = 0; printf("recv %d OOB bytes: %s\n", n, buf); } int main(int argc, char *argv[]) { int sock_fd; struct sockaddr_in my_addr; struct sockaddr_in their_addr; int sin_size, n; char buf[100]; if((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); return 1; } my_addr.sin_family = AF_INET; my_addr.sin_port = htons(MYPORT); my_addr.sin_addr.s_addr = INADDR_ANY; // 自动设置为自己的IP bzero(&(my_addr.sin_zero), 8); // 将结构的其余空间清零 if(bind(sock_fd, (struct sockaddr*)&my_addr, sizeof(struct sockaddr)) == -1) { perror("bind"); return 1; } if(listen(sock_fd, BACKLOG) == -1) { perror("listen"); return 1; } void *old_sig_urg_handle; // 保存系统默认的信号处理函数 if((old_sig_urg_handle = signal(SIGURG, sig_urg)) == SIG_ERR) { perror("signal"); return 1; } fcntl(sock_fd, F_SETOWN, getpid()); while(1) { sin_size = sizeof(struct sockaddr_in); if((new_fd = accept(sock_fd, (struct sockaddr*)&their_addr, &sin_size)) == -1) { perror("accept"); continue; } printf("server: got connection from [%s]\n", inet_ntoa(their_addr.sin_addr)); if(!fork()) { while(1) { if((n = recv(new_fd, buf, sizeof(buf)-1, 0)) <= 0) // 接收正常数据 { printf("recv EOF\n"); break; } buf[n] = 0; printf("Recv: %d bytes: %s\n", n, buf); close(new_fd); } exit(0); } } while(waitpid(-1, NULL, WNOHANG) > 0); signal(SIGURG, old_sig_urg_handle); // 恢复系统默认的信号处理函数 return 0; }
Client.c
// OOB套接字传输客户端(Client.c) #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <netdb.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #define MYPORT 4000 #define MAXDATASIZE 100 int main(int argc, char *argv[]) { int sock_fd; char buf[MAXDATASIZE]; struct hostent *he; struct sockaddr_in their_addr; if(argc < 2) { fprintf(stderr, "Usage: %s <hostname>\n", argv[0]); return 1; } if((he = gethostbyname(argv[1])) == NULL) { herror("gethostbyname"); return 1; } if((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); return 1; } their_addr.sin_family = AF_INET; their_addr.sin_port = htons(MYPORT); their_addr.sin_addr = *((struct in_addr*)he->h_addr); bzero(&(their_addr.sin_zero), 8); if(connect(sock_fd, (struct sockaddr*)&their_addr, sizeof(struct sockaddr)) == -1) { perror("connect"); return 1; } if(send(sock_fd, "123", 3, 0) == -1) { perror("send"); close(sock_fd); return 0; } printf("Send 3 bytes of normal data\n"); sleep(1); if(send(sock_fd, "4", 1, MSG_OOB) == -1) { perror("send"); close(sock_fd); return 0; } printf("Send 1 byte of OOB data\n"); sleep(1); if(send(sock_fd, "56", 2, 0) == -1) { perror("send"); close(sock_fd); return 0; } printf("Send 2 bytes of normal data\n"); sleep(1); if(send(sock_fd, "7", 1, MSG_OOB) == -1) { perror("send"); close(sock_fd); return 0; } printf("Send 1 byte of OOB data\n"); sleep(1); if(send(sock_fd, "89", 2, MSG_OOB) == -1) { perror("send"); close(sock_fd); return 0; } printf("Send 2 bytes of OOB data\n"); sleep(1); close(sock_fd); return 0; }
运行结果:
1. Server端:
[zcm@socket #39]$./myserver server: got connection from [127.0.0.1] Recv: 3 bytes: 123 recv EOF
2. 客户端:
[zcm@socket #25]$./myclient localhost Send 3 bytes of normal data Send 1 byte of OOB data Send 2 bytes of normal data Send 1 byte of OOB data Send 2 bytes of OOB data [zcm@socket #26]$
现在的疑问是:我感觉signal函数虽然调用成功了,但是没起到作用。我认为正常情况下,sig_urg()应该会被调用,但结果是好像他没有收到SIGURG信号,所以没有调用sig_urg这个函数。
若有高人能解决,小弟万分感激!