unix中的msg_oob msg_oob in unixc
win下没有unix中的信号, MSG_OOB的解决方式是 使用select 中的异常套接字: exceptfds
关于oob 的解释都在另一篇文章中了.这里不再解释, 仅仅是windows实现
oob_recv.c
// oob_recv.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include
#include
#include
#pragma comment(lib, "ws2_32.lib")
#define BUFFSIZE 8192
int _tmain(int argc, char* argv[])
{
WSADATA wsadata;
int err = 0;
if ((err =WSAStartup(MAKEWORD(2, 2), &wsadata) )!= 0){
printf("startup error : %d\n", err);
return 0;
}
SOCKADDR_IN serv_addr, client_addr;
memset(&serv_addr, 0, sizeof(serv_addr));
memset(&client_addr, 0, sizeof(client_addr));
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(9988);
serv_addr.sin_family = AF_INET;
SOCKET hListenSocket = socket(AF_INET, SOCK_STREAM, 0);
if (bind(hListenSocket, (SOCKADDR*)&serv_addr, sizeof(serv_addr)) == SOCKET_ERROR)
{
_tprintf(TEXT("bind error :%d\n"), WSAGetLastError());
closesocket(hListenSocket);
WSACleanup();
return 0;
}
if (SOCKET_ERROR == listen(hListenSocket, 10)){
_tprintf(TEXT("listen error :%d\n"), WSAGetLastError());
closesocket(hListenSocket);
WSACleanup();
}
int client_len = sizeof(client_addr);
SOCKET hRecvSocket = accept(hListenSocket, (SOCKADDR*)&client_addr,&client_len);
printf("ip:%s\n",inet_ntoa(client_addr.sin_addr));
fd_set read_set, except_set,rset,eset;
FD_ZERO(&read_set);
FD_ZERO(&except_set);
FD_SET(hRecvSocket, &read_set);
FD_SET(hRecvSocket, &except_set);
struct timeval timeout;
timeout.tv_sec = 5;
timeout.tv_usec = 0;
int n = 0 , strlen = 0;
char buf[BUFFSIZE];
while (1)
{
rset = read_set;
eset = except_set;
n = select(0,&rset,NULL,&eset,&timeout);
if (0 == n){
puts("timeout~");
continue;
}
else if (SOCKET_ERROR == n){
printf("error : %d\n", WSAGetLastError());
continue;
}
else {
//OOB 数据
if (FD_ISSET(hRecvSocket, &eset)){
strlen = recv(hRecvSocket, buf, BUFFSIZE - 1, MSG_OOB);
if (0 == strlen){
puts("on recv oob data , peer closed");
closesocket(hRecvSocket);
break;
}
printf("oob data len :%d\n", strlen);
buf[strlen] = 0;
printf("oob data buf :%s\n", buf);
}
//普通数据
if (FD_ISSET(hRecvSocket, &rset)){
strlen = recv(hRecvSocket, buf, BUFFSIZE - 1, 0);
if (0 == strlen){
puts("on recv nornal data , peer closed");
closesocket(hRecvSocket);
break;
}
buf[strlen] = 0;
printf("normal data : %s\n", buf);
}
}
}
closesocket(hListenSocket);
WSACleanup();
return 0;
}
oob_send.c
// sock.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include
#include
#include
#pragma comment(lib, "ws2_32.lib")
int _tmain(int argc, char* argv[])
{
WSADATA wsadata;
int err = 0;
if ((err = WSAStartup(MAKEWORD(2, 2), &wsadata)) != 0){
printf("startup error:%d\n", err);
return 0;
}
SOCKET hSock = socket(AF_INET, SOCK_STREAM, 0);
SOCKADDR_IN send_addr;
memset(&send_addr, 0, sizeof(send_addr));
send_addr.sin_family = AF_INET;
send_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
send_addr.sin_port = htons(9988);
if (SOCKET_ERROR == connect(hSock, (SOCKADDR*)&send_addr, sizeof(send_addr))){
_tprintf(TEXT("connect error , errno:%ld\n"),WSAGetLastError());
closesocket(hSock);
WSACleanup();
return 0;
}
puts("connect success");
char buf1[] = "data1", buf2[] = "data2";
char oob_buf1[] = "oob_data1", oob_buf2[] = "oob_data2";
send(hSock, buf1, strlen(buf1), 0);
//oob
send(hSock, oob_buf1, strlen(oob_buf1), MSG_OOB);
send(hSock, buf2, strlen(buf2), 0);
//oob
send(hSock, oob_buf2, strlen(oob_buf2), MSG_OOB);
closesocket(hSock);
WSACleanup();
return 0;
}