WinSock Introduction MCS 4613 – Computer Networks David Brown Overview Sockets are used to connect between two processes on the network There is a client and server process Server process creates a socket and listens for a connection Client process creates a socket and connects to server Sockets support different network standards Discuss use of sockets for TCP/IP protocols Nov 3, 2011 MCS 4613 Computer Networks Prof David Brown 2 Server Steps 1. 2. 3. 4. 5. 6. 7. Initialize Winsock Create a socket Bind the socket Listen on the socket for a client Accept a connection from a client Receive and send data Disconnect Nov 3, 2011 MCS 4613 Computer Networks Prof David Brown 3 Building an application Must call WSAStartup before using sockets When done with sockets call WSACleanup #include <winsock2.h> #include <stdio.h> int main(int argc, char **argv) { WSADATA wsaData; // Initialize Winsock version 2.2 WSAStartup(MAKEWORD(2,2), &wsaData); printf("Winsock DLL status is %s.\n", wsaData.szSystemStatus); // Code to handle socket // Cleanup socket WSACleanup(); } Nov 3, 2011 MCS 4613 Computer Networks Prof David Brown 4 Client/Server Creating a Socket Simplest way is with a call to socket Sockets support different protocols SOCKET Socket; // Create a new socket to make a client or server connection. // AF_INET = 2, The Internet Protocol version 4 (IPv4) address family, TCP protocol Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(Socket == INVALID_SOCKET) { printf(“Socket() failed! Error code: %ld\n", WSAGetLastError()); // Do the clean up WSACleanup(); // Exit with error return -1; } Nov 3, 2011 MCS 4613 Computer Networks Prof David Brown 5 Server Socket Address Structure Server must specify what address to listen on There is a special address for any address SOCKADDR_IN ServerAddr; unsigned int Port = 21073; // Set up a SOCKADDR_IN structure that will be used to connect // to a listening server on port 21073. // IPv4 ServerAddr.sin_family = AF_INET; // Port no. ServerAddr.sin_port = htons(Port); // The IP address ServerAddr.sin_addr.s_addr = htonl (INADDR_ANY); Nov 3, 2011 MCS 4613 Computer Networks Prof David Brown 6 Server Bind to socket The SOCKADDR_IN structure must be binded with the socket NOTE: SOCKADDR_IN vs. SOCKADDR // Associate the address information with the socket using bind. // Call the bind function, passing the created socket and the sockaddr_in // structure as parameters. Check for general errors. if (bind(Socket, (SOCKADDR *)&ServerAddr, sizeof(ServerAddr)) == SOCKET_ERROR) { printf("Server: bind() failed! Error code: %ld.\n", WSAGetLastError()); // Close the socket closesocket(Socket); // Do the clean up WSACleanup(); // and exit with error return -1; } else MCS 4613 Computer Networks Nov 3, 2011 7 printf("Server: bind() is OK!\n"); Prof David Brown Server Listen to Socket Server must listen for a connection Backlog is number of connections to allow in the queue // Listen for client connections. We use a backlog of 5, which // is normal for many applications. if (listen(Socket, 5) == SOCKET_ERROR) { printf("Server: listen(): Error listening on socket %ld.\n", WSAGetLastError()); // Close the socket closesocket(Socket); // Do the clean up WSACleanup(); // Exit with error return -1; } Nov 3, 2011 MCS 4613 Computer Networks Prof David Brown 8 Server Accept connection Once a socket is listening you have to call Accept to accept any connection Note: code below assumes blocking socket // Accept a new connection when one arrives. NewConnection = accept(Socket, NULL, NULL); if (NewConnection == SOCKET_ERROR) { printf(“Server: accept() failed! Error code: %ld\n", WSAGetLastError()); // Close the socket closesocket(Socket); // Do the clean up WSACleanup(); // Exit with error return -1; } Nov 3, 2011 MCS 4613 Computer Networks Prof David Brown 9 Client Steps 1. 2. 3. 4. 5. Initialize Winsock Create a socket Connect to the server Send and receive data Disconnect Nov 3, 2011 MCS 4613 Computer Networks Prof David Brown 10 Client Socket Address Structure sockaddr structure is used to either connect or listen to a socket It specifies the protocol, the port and the IP address SOCKADDR_IN ServerAddr; unsigned int Port = 21073; // Set up a SOCKADDR_IN structure that will be used to connect // to a listening server on port 21073. For demonstration // purposes, let's assume our server's IP address is 127.0.0.1 or localhost // IPv4 ServerAddr.sin_family = AF_INET; // Port no. ServerAddr.sin_port = htons(Port); // The IP address ServerAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); Nov 3, 2011 MCS 4613 Computer Networks Prof David Brown 11 Client Connect to Socket Connect to Socket before transmitting data Similar to server bind/listen but all in one call // Make a connection to the server with socket SendingSocket. RetCode = connect(Socket, (SOCKADDR *) &ServerAddr, sizeof(ServerAddr)); if(RetCode != 0) { printf("Client: connect() failed! Error code: %ld\n", WSAGetLastError()); // Close the socket closesocket(Socket); // Do the clean up WSACleanup(); // Exit with error return -1; } Nov 3, 2011 MCS 4613 Computer Networks Prof David Brown 12 Client/Server Send data Once connection is made you can send data Bytes actually sent may not be the same number of bytes requested to be sent Server should send to the socket returned by accept Data can be sent after one end closes connection // Sends some data BytesSent = send(Socket, sendbuf, strlen(sendbuf), 0); if (BytesSent == SOCKET_ERROR) printf("Client: send() error %ld.\n", WSAGetLastError()); Nov 3, 2011 MCS 4613 Computer Networks Prof David Brown 13 Client/Server Receive data Recv will block until data is available Recv returns 0 bytes if connection is closed Recv can receive data after connection is closed Server should use socket returned by accept BytesReceived = recv(RecvSocket, recvbuf, sizeof(recvbuf)-1, 0); recvbuf[BytesReceived] = ‘\0’; if (BytesReceived == SOCKET_ERROR) printf("Client: recv() error %ld.\n", WSAGetLastError()); Nov 3, 2011 MCS 4613 Computer Networks Prof David Brown 14 Client/Server Shutdown Connection You should shutdown the connection when done Both sides should shut down the connection Shutdown can be for SD_SEND, SD_RECV, or SD_BOTH Server should use socket returned by accept // Shutdown sending of data if( shutdown(Socket, SD_SEND) != 0) printf("Client: Well, there is something wrong with the shutdown(). The error code: %ld\n", WSAGetLastError()); else printf("Client: shutdown() looks OK...\n\n"); Nov 3, 2011 MCS 4613 Computer Networks Prof David Brown 15 Client/Server Close socket Once a socket is completely done it should be closed Sockets returned from accept do not have to be closed. if(closesocket(Socket) != 0) printf("Server: Cannot close socket. Error code: %ld\n", WSAGetLastError()); else printf("Server: Closing socket...\n"); Nov 3, 2011 MCS 4613 Computer Networks Prof David Brown 16 Client/Server Cleanup WSA You should call WSACleanup when done with all sockets if(WSACleanup() != 0) printf("Client: WSACleanup() failed!...\n"); Nov 3, 2011 MCS 4613 Computer Networks Prof David Brown 17 Miscellaneous Information The information in this introduction describes very simple socket based programs Handling of asyncronous calls, multiple simultaneous connections and other topics are beyond this introduction The server I provided uses the function “select” to provide a timeout feature For more information on sockets in windows go to http://msdn.microsoft.com/en-us/library/ms740673(VS.85).aspx http://docs.microsoft.com/en-us/windows/win32/winsock/gettingstarted-with-winsock Nov 5, 2019 MCS 4613 Computer Networks Prof David Brown 18