unix中的msg_oob msg_oob in unixc
win下沒有unix中的信號, MSG_OOB的解決方式是 使用select 中的異常套接字: exceptfdssegmentfault
關於oob 的解釋都在另外一篇文章中了.這裏再也不解釋, 僅僅是windows實現windows
oob_recv.capp
// oob_recv.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <stdlib.h> #include <winsock2.h> #include <Windows.h> #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.csocket
// sock.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <stdlib.h> #include <winsock2.h> #include <Windows.h> #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; }