Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define WIN32_LEAN_AND_MEAN
- //http://stackoverflow.com/questions/14823635/winsock-bind-before-connects-results-in-wsaeaddrnotavail-the-requested-address
- #include <windows.h>
- #include <winsock2.h>
- #include <ws2tcpip.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <iostream>
- #include <string>
- #include <vector>
- // Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib
- #pragma comment (lib, "Ws2_32.lib")
- #pragma comment (lib, "Mswsock.lib")
- #pragma comment (lib, "AdvApi32.lib")
- using std::cout;
- using std::endl;
- using std::vector;
- using std::string;
- using std::exception;
- const int MAX_INTERFACES = 20;
- const int DEFAULT_BUFLEN = 1024;
- const char * DEFAULT_HOST = "10.60.35.10";
- const char * DEFAULT_PORT = "80";
- class WSAException : public exception
- {
- public:
- WSAException(string message);
- virtual const char* what() const throw() { return _fullMessage.c_str(); }
- int errorCode() { return _errorCode; }
- private:
- int _errorCode;
- string _fullMessage;
- };
- void throwIfError(int result, string msg);
- void throwIfError(WSAException ex);
- void getLocalAddresses(vector<sockaddr> & localAddresses, ULONG subnet, ULONG subnetMask);
- void getServerAddresses(vector<sockaddr> & serverAddresses, string host, string port);
- std::ostream& operator<<(std::ostream& os, const sockaddr_in& addr);
- std::ostream& operator<<(std::ostream& os, const sockaddr& addr);
- template<class T> int inline findAndReplace(T& source, const T& find, const T& replace);
- int main(int argc, char* argv[])
- {
- WSADATA wsaData;
- int iResult;
- char buffer[DEFAULT_BUFLEN];
- // Get default server hostname
- string host(argc != 2 ? DEFAULT_HOST : argv[1]);
- // Build HTTP request
- string request = "GET http://";
- request += host;
- request += " HTTP/1.0\r\nHost: ";
- request += host;
- request += "\r\n\r\n";
- try
- {
- // Initialize Winsock
- throwIfError(WSAStartup(MAKEWORD(2,2), &wsaData), "WSAStartup failed with error");
- // Get a vector of all local addresses on the 10.0.0.0 subnet
- vector<sockaddr> localAddresses;
- getLocalAddresses(localAddresses, 0x0a, 0xff);
- // Get a vector of server addresses
- vector<sockaddr> remoteAddresses;
- getServerAddresses(remoteAddresses, host, DEFAULT_PORT);
- auto localAddress = localAddresses.begin();
- while(true)
- {
- // Select the next local address in turn, looping back to the start when we reach the end
- if (++localAddress == localAddresses.end())
- localAddress = localAddresses.begin();
- // Select the first server address (won't worry about any others for now)
- sockaddr remoteAddr = *remoteAddresses.begin();
- // Create a SOCKET for connecting to server
- SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- throwIfError(sock, "Socket creation failed");
- // Bind the socket locally to a specific interface
- iResult = bind(sock, &*localAddress, sizeof(*localAddress));
- WSAException ex1("Unable to bind to local net");
- cout << "BIND result (" << iResult << ") binding locally to " << *localAddress << endl;
- throwIfError(ex1);
- // Connect to the server.
- iResult = connect( sock, &remoteAddr, sizeof(remoteAddr));
- WSAException ex2("Unable to connect to server");
- cout << "CONNECT result (" << iResult << ") connecting remotely to " << remoteAddr << endl;
- throwIfError(ex2);
- // Send an initial buffer
- int bytesSent = send( sock, request.c_str(), request.length(), 0 );
- WSAException ex3("Send error");
- cout << "Bytes Sent: " << bytesSent << endl;
- throwIfError(ex3);
- // Receive until the peer closes the connection
- string response = " ";
- int responseLen = DEFAULT_BUFLEN;
- do
- {
- responseLen = recv(sock, (char*)&buffer, DEFAULT_BUFLEN, 0);
- if ( responseLen > 0 )
- response+= string(buffer).substr(0,responseLen);
- else if ( responseLen == 0 )
- cout << "Connection closed" << endl;
- else
- cout << WSAException("recv failed").what() << endl;
- } while( responseLen > 0);
- // Indent the html response so that the console is not so cluttered
- findAndReplace(response, string("\n"), string("\n "));
- cout << response << endl << endl << endl << endl;
- // cleanup
- closesocket(sock);
- }
- }
- catch(WSAException& ex)
- {
- cout << ex.what() << endl;
- }
- catch(exception& ex)
- {
- cout << ex.what() << endl;;
- }
- WSACleanup();
- return 0;
- }
- void getServerAddresses(vector<sockaddr> & serverAddresses, string host, string port)
- {
- // Resolve the server address(es) and port
- addrinfo *servAddr = NULL;
- struct addrinfo hints;
- ZeroMemory( &hints, sizeof(hints) );
- hints.ai_flags = AI_NUMERICSERV;
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_protocol = IPPROTO_TCP;
- throwIfError(getaddrinfo(host.c_str(), port.c_str(), &hints, &servAddr), "getaddrinfo failed");
- struct addrinfo *serverAddress = servAddr;
- while(serverAddress != NULL)
- {
- serverAddresses.push_back(*serverAddress->ai_addr);
- serverAddress=serverAddress->ai_next;
- }
- freeaddrinfo(servAddr);
- }
- void getLocalAddresses(vector<sockaddr> & localAddresses, ULONG subnet, ULONG subnetMask)
- {
- SOCKET sd = WSASocket(AF_INET, SOCK_DGRAM, 0, 0, 0, 0);
- throwIfError(sd, "Failed to get a socket");
- INTERFACE_INFO InterfaceList[20];
- ULONG nBytesReturned;
- int iResult = WSAIoctl(sd, SIO_GET_INTERFACE_LIST, 0, 0, &InterfaceList, sizeof(InterfaceList), &nBytesReturned, 0, 0);
- throwIfError(iResult, "Failed calling WSAIoctl");
- int nNumInterfaces = nBytesReturned / sizeof(INTERFACE_INFO);
- for (int i = 0; i < nNumInterfaces; ++i)
- {
- sockaddr_in *pAddress;
- pAddress = (sockaddr_in *) & (InterfaceList[i].iiAddress);
- if ((pAddress->sin_addr.s_addr & subnetMask) == subnet)
- {
- localAddresses.push_back(*(sockaddr*)&(*pAddress));
- }
- }
- }
- template<class T>
- int inline findAndReplace(T& source, const T& find, const T& replace)
- {
- int num=0;
- auto fLen = find.size();
- auto rLen = replace.size();
- for (int pos=0; (pos=source.find(find, pos))!=T::npos; pos+=rLen)
- {
- num++;
- source.replace(pos, fLen, replace);
- }
- return num;
- }
- void throwIfError(int result, string msg)
- { if(result == SOCKET_ERROR) { throw WSAException(msg); }; }
- void throwIfError(WSAException ex)
- { if(ex.errorCode()) { throw ex; }; }
- std::ostream& operator<<(std::ostream& os, const sockaddr_in& addr)
- { os << inet_ntoa(addr.sin_addr) << ":" << htons(addr.sin_port); return os; }
- std::ostream& operator<<(std::ostream& os, const sockaddr& addr)
- { return operator<<(os, *reinterpret_cast<sockaddr_in const *>(&addr)); }
- WSAException::WSAException(string message)
- {
- _errorCode = WSAGetLastError();
- LPSTR errorString = NULL;
- FormatMessageA(
- FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
- 0, _errorCode, 0, (LPSTR)&errorString, 0, 0);
- _fullMessage = "ERROR: ";
- _fullMessage += message;
- _fullMessage += " WSAError (";
- _fullMessage += std::to_string(static_cast<long long>(_errorCode));
- _fullMessage += ") ";
- _fullMessage += errorString;
- LocalFree(errorString);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement