[WS2_32_APITESTS] Add nonblocking tests
[reactos.git] / rostests / apitests / ws2_32 / nonblocking.c
1 /*
2 * PROJECT: ReactOS api tests
3 * LICENSE: GPL - See COPYING in the top level directory
4 * PURPOSE: Test for nonblocking sockets
5 * PROGRAMMERS: Peter Hater
6 */
7
8 #include <apitest.h>
9
10 #include <stdio.h>
11 #include <windows.h>
12 #include <winsock2.h>
13
14 #define SVR_PORT 5000
15 #define WAIT_TIMEOUT_ 10000
16 #define EXIT_FLAGS (FD_ACCEPT|FD_CONNECT)
17
18 START_TEST(nonblocking)
19 {
20 WSADATA WsaData;
21 SOCKET ServerSocket = INVALID_SOCKET,
22 ClientSocket = INVALID_SOCKET;
23 struct sockaddr_in server_addr_in;
24 struct sockaddr_in addr_remote;
25 struct sockaddr_in addr_con_loc;
26 int nConRes, err;
27 int addrsize;
28 SOCKET sockaccept;
29 ULONG ulValue = 1;
30 DWORD dwFlags = 0, dwLen, dwAddrLen;
31 fd_set readfds, writefds, exceptfds;
32 struct timeval tval = { 0 };
33 char address[100];
34
35 if (WSAStartup(MAKEWORD(2, 2), &WsaData) != 0)
36 {
37 skip("WSAStartup failed\n");
38 return;
39 }
40
41 ServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
42 ClientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
43
44 if (ServerSocket == INVALID_SOCKET)
45 {
46 skip("ERROR: Server socket creation failed\n");
47 return;
48 }
49 if (ClientSocket == INVALID_SOCKET)
50 {
51 skip("ERROR: Client socket creation failed\n");
52 closesocket(ServerSocket);
53 return;
54 }
55 server_addr_in.sin_family = AF_INET;
56 server_addr_in.sin_addr.s_addr = INADDR_ANY;
57 server_addr_in.sin_port = htons(SVR_PORT);
58
59 // server inialialization
60 trace("Initializing server and client connections ...\n");
61 err = bind(ServerSocket, (struct sockaddr*)&server_addr_in, sizeof(server_addr_in));
62 ok(err == 0, "ERROR: server bind failed\n");
63 err = ioctlsocket(ServerSocket, FIONBIO, &ulValue);
64 ok(err == 0, "ERROR: server ioctlsocket FIONBIO failed\n");
65
66 // client inialialization
67 err = ioctlsocket(ClientSocket, FIONBIO, &ulValue);
68 ok(err == 0, "ERROR: client ioctlsocket FIONBIO failed\n");
69
70 // listen
71 trace("Starting server listening mode ...\n");
72 err = listen(ServerSocket, 2);
73 ok(err == 0, "ERROR: cannot initialize server listen\n");
74
75 trace("Starting client to server connection ...\n");
76 // connect
77 server_addr_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
78 server_addr_in.sin_port = htons(SVR_PORT);
79 nConRes = connect(ClientSocket, (struct sockaddr*)&server_addr_in, sizeof(server_addr_in));
80 ok(nConRes == SOCKET_ERROR, "ERROR: client connect() result is not SOCKET_ERROR\n");
81 ok(WSAGetLastError() == WSAEWOULDBLOCK, "ERROR: client connect() last error is not WSAEWOULDBLOCK\n");
82 FD_ZERO(&readfds);
83 FD_ZERO(&writefds);
84 FD_ZERO(&exceptfds);
85 FD_SET(ServerSocket, &readfds);
86
87 while (dwFlags != EXIT_FLAGS)
88 {
89 addrsize = sizeof(addr_con_loc);
90 err = getsockname(ClientSocket, (struct sockaddr*)&addr_con_loc, &addrsize);
91 if (err == 0)
92 {// client connected
93 dwLen = sizeof(addr_con_loc);
94 dwAddrLen = sizeof(address);
95 err = WSAAddressToStringA((PSOCKADDR)&addr_con_loc, dwLen, NULL, address, &dwAddrLen);
96 if (err == 0)
97 {
98 trace("Event FD_CONNECT...\n");
99 dwFlags |= FD_CONNECT;
100 err = recv(ClientSocket, address, dwAddrLen, 0);
101 ok(err == -1, "ERROR: error reading data from connected socket, error %d\n", WSAGetLastError());
102 ok(WSAGetLastError() == WSAEWOULDBLOCK, "ERROR: client connect() last error is not WSAEWOULDBLOCK\n");
103 err = send(ClientSocket, address, dwAddrLen, 0);
104 ok(err == dwAddrLen, "ERROR: error writing data to connected socket, error %d %d\n", err, WSAGetLastError());
105 }
106 else
107 {
108 trace("WSAAddressToStringA failed %d\n", WSAGetLastError());
109 }
110 }
111
112 err = select(1, &readfds, &writefds, &exceptfds, &tval);
113 if (err == 1 && FD_ISSET(ServerSocket, &readfds))
114 {// connection ready to be accepted
115 trace("Event FD_ACCEPT...\n");
116 addrsize = sizeof(addr_remote);
117 sockaccept = accept(ServerSocket, (struct sockaddr*)&addr_remote, &addrsize);
118 ok(sockaccept != INVALID_SOCKET, "ERROR: Connection accept function failed, error %d\n", WSAGetLastError());
119 dwFlags |= FD_ACCEPT;
120 dwLen = sizeof(addr_remote);
121 dwAddrLen = sizeof(address);
122 err = WSAAddressToStringA((PSOCKADDR)&addr_remote, dwLen, NULL, address, &dwAddrLen);
123 ok(err == 0, "WSAAddressToStringA, error %d\n", WSAGetLastError());
124 ok(dwAddrLen > 7, "len <= 7\n");
125 err = send(sockaccept, address, dwAddrLen, 0);
126 ok(err == dwAddrLen, "ERROR: error sending data on accepted socket, error %d\n", WSAGetLastError());
127 }
128 }
129
130 closesocket(sockaccept);
131 closesocket(ServerSocket);
132 closesocket(ClientSocket);
133
134 WSACleanup();
135 }