/* * PROJECT: ReactOS api tests * LICENSE: GPL - See COPYING in the top level directory * PURPOSE: Test for nonblocking sockets * PROGRAMMERS: Peter Hater */ #include "ws2_32.h" #define SVR_PORT 5000 #define WAIT_TIMEOUT_ 10000 #define EXIT_FLAGS (FD_ACCEPT|FD_CONNECT) START_TEST(nonblocking) { WSADATA WsaData; SOCKET ServerSocket = INVALID_SOCKET, ClientSocket = INVALID_SOCKET; struct sockaddr_in server_addr_in; struct sockaddr_in addr_remote; struct sockaddr_in addr_con_loc; int nConRes, err; int addrsize; SOCKET sockaccept; ULONG ulValue = 1; DWORD dwFlags = 0, dwLen, dwAddrLen; fd_set readfds, writefds, exceptfds; struct timeval tval = { 0 }; char address[100]; if (!winetest_interactive) { skip("ROSTESTS-247: Skipping ws2_32_apitest:nonblocking because it times out on testbot\n"); return; } if (WSAStartup(MAKEWORD(2, 2), &WsaData) != 0) { skip("WSAStartup failed\n"); return; } ServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); ClientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (ServerSocket == INVALID_SOCKET) { skip("ERROR: Server socket creation failed\n"); return; } if (ClientSocket == INVALID_SOCKET) { skip("ERROR: Client socket creation failed\n"); closesocket(ServerSocket); return; } server_addr_in.sin_family = AF_INET; server_addr_in.sin_addr.s_addr = INADDR_ANY; server_addr_in.sin_port = htons(SVR_PORT); // Server initialization. trace("Initializing server and client connections ...\n"); err = bind(ServerSocket, (struct sockaddr*)&server_addr_in, sizeof(server_addr_in)); ok(err == 0, "ERROR: server bind failed\n"); err = ioctlsocket(ServerSocket, FIONBIO, &ulValue); ok(err == 0, "ERROR: server ioctlsocket FIONBIO failed\n"); // Client initialization. err = ioctlsocket(ClientSocket, FIONBIO, &ulValue); ok(err == 0, "ERROR: client ioctlsocket FIONBIO failed\n"); // listen trace("Starting server listening mode ...\n"); err = listen(ServerSocket, 2); ok(err == 0, "ERROR: cannot initialize server listen\n"); trace("Starting client to server connection ...\n"); // connect server_addr_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK); server_addr_in.sin_port = htons(SVR_PORT); nConRes = connect(ClientSocket, (struct sockaddr*)&server_addr_in, sizeof(server_addr_in)); ok(nConRes == SOCKET_ERROR, "ERROR: client connect() result is not SOCKET_ERROR\n"); ok(WSAGetLastError() == WSAEWOULDBLOCK, "ERROR: client connect() last error is not WSAEWOULDBLOCK\n"); FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds); FD_SET(ServerSocket, &readfds); while (dwFlags != EXIT_FLAGS) { addrsize = sizeof(addr_con_loc); err = getsockname(ClientSocket, (struct sockaddr*)&addr_con_loc, &addrsize); if (err == 0) {// client connected dwLen = sizeof(addr_con_loc); dwAddrLen = sizeof(address); err = WSAAddressToStringA((PSOCKADDR)&addr_con_loc, dwLen, NULL, address, &dwAddrLen); if (err == 0) { trace("Event FD_CONNECT...\n"); dwFlags |= FD_CONNECT; err = recv(ClientSocket, address, dwAddrLen, 0); ok(err == -1, "ERROR: error reading data from connected socket, error %d\n", WSAGetLastError()); ok(WSAGetLastError() == WSAEWOULDBLOCK, "ERROR: client connect() last error is not WSAEWOULDBLOCK\n"); err = send(ClientSocket, address, dwAddrLen, 0); ok(err == dwAddrLen, "ERROR: error writing data to connected socket, error %d %d\n", err, WSAGetLastError()); } else { trace("WSAAddressToStringA failed %d\n", WSAGetLastError()); } } err = select(1, &readfds, &writefds, &exceptfds, &tval); if (err == 1 && FD_ISSET(ServerSocket, &readfds)) {// connection ready to be accepted trace("Event FD_ACCEPT...\n"); addrsize = sizeof(addr_remote); sockaccept = accept(ServerSocket, (struct sockaddr*)&addr_remote, &addrsize); ok(sockaccept != INVALID_SOCKET, "ERROR: Connection accept function failed, error %d\n", WSAGetLastError()); dwFlags |= FD_ACCEPT; dwLen = sizeof(addr_remote); dwAddrLen = sizeof(address); err = WSAAddressToStringA((PSOCKADDR)&addr_remote, dwLen, NULL, address, &dwAddrLen); ok(err == 0, "WSAAddressToStringA, error %d\n", WSAGetLastError()); ok(dwAddrLen > 7, "len <= 7\n"); err = send(sockaccept, address, dwAddrLen, 0); ok(err == dwAddrLen, "ERROR: error sending data on accepted socket, error %d\n", WSAGetLastError()); } } closesocket(sockaccept); closesocket(ServerSocket); closesocket(ClientSocket); WSACleanup(); }