I made a simple client program who connect to server via port 80;
int v=connect(mysocket,(struct sockaddr *)&server,sizeof(server));
if(v==SOCKET_ERROR){
cout<<"error connecting to server";
}
if (v==0) cout<<"connected"<<endl;
its says connect return 0 if success.
but i get the error;
can you please tell me when i must use htonl or htons i used only server.sin_port=htons(80);
should i use server.sin_addr.s_addr=inet_addr("someip_ignorethis"); or i must use
server.sin_addr.s_addr=htonl(inet_addr("someip_ignorethis"));
what is the problem WHY AND WHEN i need to use host to network conversation,how does it make my program portable???.
what socket i must use? socket version 2,2?
THNAKS FOR THE HELP!
I get 10038 ERROR HELP FIX MY CODE pastebin.com/4pdqsGqW
If you had bothered to use your debugger and debug the code yourself, you would have found that your mySocket variable is always 0, because you are not initializing it correctly.
This line:
if (mysocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)==INVALID_SOCKET){
Is effectively the same as this:
if (mysocket=(socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)==INVALID_SOCKET)){
If socket() succeeds, ==INVALID_SOCKET evaluates as false, so 0 is assigned to mysocket. Read up on Operator Precedence. The == operator has a higher precedence than the = operator.
To fix it, change that line to this instead:
if ((mysocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==INVALID_SOCKET){
Or better, get out of the habit of assigning and comparing a variable in the same statement:
mysocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if (mysocket==INVALID_SOCKET){
Also, if you had bothered to pay attention to your compiler's output messages, you would have seen that your "CONNECTED!" message is code that is never reached, because it is inside the curly braces for when connect() fails, but there is a return before you print the message.
Try this code instead:
#include <winsock2.h>
#include <iostream.h>
#include <windows.h>
//#define portnumber 80
using namespace std;
//Winsock Library
int main(int argc, char* argv[])
{
WSADATA ws = {0};
int v = WSAStartup(MAKEWORD(2,2), &ws);
if (v != 0)
{
cout << "error initialising winsock: " << v << endl;
getchar();
return 1;
}
cout << "winsock started" << endl;
SOCKET mysocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (mysocket == INVALID_SOCKET)
{
cout << "error creating socket: " << WSAGetLastError() << endl;
getchar();
return 1;
}
cout << "socket created" << endl;
struct sockaddr_in server = {0};
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr("84.95.234.174");
//cout << inet_ntoa(server.sin_addr) << endl;
server.sin_port = htons(80);
if (connect(mysocket, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
{
cout << "error connecting to server: " << WSAGetLastError() << endl;
getchar();
return 1;
}
cout << "CONNECTED!" << endl;
getchar();
closesocket(mysocket);
return 0;
}
10038 is WSAENOTSOCK. Clearly the value of socket is invalid.
You should have found all that out for yourself before you posted, and looked up what the error meant as well.
Personally, I use this and it never fails me..
struct addrinfo *it = nullptr, *result = nullptr;
getaddrinfo(Address.c_str(), nullptr, nullptr, &result);
for (it = result; it != nullptr; it = it->ai_next)
{
sockaddr_ipv4 = reinterpret_cast<sockaddr_in*>(it->ai_addr);
Address = inet_ntoa(sockaddr_ipv4->sin_addr);
if (Address != "0.0.0.0") break;
}
freeaddrinfo(result);
And I use:
struct sockaddr_in SockAddr;
memset(&SockAddr, 0, sizeof(SockAddr));
SockAddr.sin_port = htons(Port);
SockAddr.sin_family = AF_INET;
SockAddr.sin_addr.s_addr = Address == "INADDR_ANY" ? htonl(INADDR_ANY) : inet_addr(Address.c_str());
if (connect(socket, reinterpret_cast<SOCKADDR*>(&SockAddr), sizeof(SockAddr)) == SOCKET_ERROR)
{
//print error.. clean up..
}
What it does is it checks the address. If it is INADDR_ANY, then it will use htonl. If not, it uses inet_addr to convert the address into an IP. Htonl on the other hand just converts the address into network byte order.
Related
I'm trying to make a winsock server and I want to display the client's ip on the server when he connects but that's where there is a problem. Every time I try to connect it display 204.204.204.204. I tried to connect with another computer but the result was the same.
result in localhost
After this, I started looking for people having the same problem as me on this website and I found several people who had the same as me but they all had either the accept or the inet_ntop function that wasn't working correctly. So I check and none of this two functions return an error. Maybe I'm stupid but I really can't figured out what's the problem. (btw english is not my first language so please tell me if you noticed or if my english isn't too bad)
the part of the code that isn't working
sockaddr_in from;
int clientlen = sizeof(from);
// accept
SOCKET client = accept(server, (SOCKADDR*)&client, &clientlen);
if (client == INVALID_SOCKET)
{
std::cout << "Error in accept(): " << WSAGetLastError << std::endl;
WSACleanup();
}
else
{
char clientIp[17];
if (inet_ntop(AF_INET, &from.sin_addr, clientIp, 17) == NULL)
{
std::cout << "Can't get the client's ip: " << WSAGetLastError() << std::endl;
}
std::cout << "ip connected: " << clientIp << std::endl;
the whole code if you need it
#include <iostream>
#include <WinSock2.h>
#include <WS2tcpip.h>
#include <string>
#pragma comment(lib, "ws2_32.lib")
int main()
{
std::cout << "--- Tcp/ip Server ---" << std::endl;
WSADATA wsa;
WSAStartup(MAKEWORD(2, 2), &wsa);
SOCKET server = socket(AF_INET, SOCK_STREAM, 0);
if (server == INVALID_SOCKET)
{
std::cout << "error in SOCKET(): "<< WSAGetLastError() << std::endl;
WSACleanup();
}
sockaddr_in s;
s.sin_family = AF_INET;
s.sin_addr.s_addr = INADDR_ANY;
s.sin_port = htons(52000);
// bind
if (bind(server, (sockaddr*)&s, sizeof(s)) == SOCKET_ERROR)
{
std::cout << "Error: bind()" << std::endl;
}
//listen
if (listen(server, SOMAXCONN) == SOCKET_ERROR)
{
std::cout << "Error in listen(): " << WSAGetLastError() << std::endl;
WSACleanup();
}
sockaddr_in from;
int clientlen = sizeof(from);
// accept
SOCKET client = accept(server, (SOCKADDR*)&client, &clientlen);
if (client == INVALID_SOCKET)
{
std::cout << "Error in accept(): " << WSAGetLastError << std::endl;
WSACleanup();
}
else
{
char clientIp[17];
if (inet_ntop(AF_INET, &from.sin_addr, clientIp, 17) == NULL)
{
std::cout << "Can't get the client's ip: " << WSAGetLastError() << std::endl;
}
std::cout << "ip connected: " << clientIp << std::endl;
// the code isn't finished yet
system("pause");
WSACleanup();
}
return 0;
}
You are passing the address of the wrong variable in the second parameter of accept().
You are passing the address of your SOCKET client variable that you are about to assign the result of accept() to. C++ allows a variable's address to be taken when declaring and initializing the variable in the same statement. But that is not what you want in this case. You need to pass the address of your sockaddr_in from variable instead:
sockaddr_in from;
int clientlen = sizeof(from);
// accept
SOCKET client = accept(server, (SOCKADDR*)&from, &clientlen); // <-- &from instead of &client
You are leaving your from variable uninitialized, and your compiler fills uninitialized variables with 0xCC (decimal 204) bytes in debug mode, so that is why you end up seeing 204.204.204.204 (hex 0xCC 0xCC 0xCC 0xCC) from inet_ntop() when you don't initialize your from variable properly.
I have a working code of the server application.
Now I need to use cpp_int in my project.
However, when I just try to include boost/multiprecision/cpp_int.hpp
accept(listeningSocket, (sockaddr*)&client, &sizeofclient);
returns INVALID_SOCKET, and programm terminates with the code 3.
This is a code of server.cpp
#include <iostream>
#include <Ws2tcpip.h>
//#include <boost/multiprecision/cpp_int.hpp> // reason of the probmlem
#pragma comment(lib, "ws2_32.lib")
constexpr auto MSIZE = 4096;
using namespace std;
int main()
{
WSADATA wsData;
WORD ver = MAKEWORD(2, 2);
if (WSAStartup(ver, &wsData) != 0)
{
cerr << "Can't initialise winsock\nQuiting...\n";
return 1;
}
SOCKET listeningSocket = socket(AF_INET, SOCK_STREAM, 0);
if (listeningSocket == INVALID_SOCKET)
{
cerr << "Can't create a socket!\nQuiting...\n";
return 2;
}
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(54000);
hint.sin_addr.S_un.S_addr = INADDR_ANY;
bind(listeningSocket, (sockaddr*)&hint, sizeof(hint));
listen(listeningSocket, SOMAXCONN);
cout << "Listenning\n";
sockaddr_in client;
int sizeofclient = sizeof(client);
SOCKET clientSocket = accept(listeningSocket, (sockaddr*)&client, &sizeofclient);
if (clientSocket == INVALID_SOCKET)
{
cerr << "Invalid socket.\nQuiting...\n";
return 3;
}
char host[NI_MAXHOST];
char service[NI_MAXHOST];
ZeroMemory(host, NI_MAXHOST);
ZeroMemory(service, NI_MAXHOST);
char buf[MSIZE];
while (1)
{
ZeroMemory(buf, MSIZE);
int bytesReceived = recv(clientSocket, buf, MSIZE, 0);
if (bytesReceived == SOCKET_ERROR)
{
cerr << "Error in recv()\n";
break;
}
if (bytesReceived == 0)
{
cout << "Client disconnected" << endl;
break;
}
if (strcmp("\r\n", buf) != 0)
{
cout << "(Request from " << host << ") >> " << buf << endl;
if (strcmp(buf, "hello") == 0)
{
char response[100] = "Greetings!\n\r";
send(clientSocket, response, sizeof(response) + 1, 0);
}
else
{
char response[100] = "Invalid command!\n\r";
send(clientSocket, response, sizeof(response) + 1, 0);
}
}
}
cout << "Quiting program\n";
return 0;
}
Any ideas?
The problem is a side effect of your use of using namespace std;.
When you include <boost/multiprecision/cpp_int.hpp>, it pulls in std::bind() from C++'s <functional> header, and that is the function your code ends up calling instead of Winsock's bind() function. Thus, listen() and accept() fail because the server socket is not bound to a network interface (and your code is not checking for errors on bind() and listen()). Had you checked the error codes for listen() and accept(), you would have seen that they were both reporting WSAEINVAL (meaning "The socket has not been bound with bind" and "The listen function was not invoked prior to accept", respectively).
You need to either
Get rid of using namespace std;, and then explicitly use the std:: prefix where needed (this is the preferred solution!)
when calling bind(), you can prefix it with :: to tell the compiler that you want to call the bind() function from the global namespace (Win32 APIs, like Winsock, do not use namespaces in C++) rather than the one from the std namespace.
I'm currently working on a simple server/client application using C++ in Visual Studio to send a message from one computer to another via an Ethernet/LAN cable connection. I am using code for both client and server that I found online.
When I run the programs on the same computer, I can receive messages from the server. However, if I run the client program on one computer and run the server program on another computer, I do not receive any messages.
Since I am just using an Ethernet cable to communicate between two computers, I set the IP addresses (from Local Network Sharing, Adapter settings, TCP/IPv4) to be specific for both computers, such that the server computer is 10.0.1.2 and the client computer is 10.0.1.1, both with a subnet mask of 255.255.255.0. And then, in the code, I use addr.sin_addr.s_addr = inet_addr("10.0.1.2") for server and addr.sin_addr.s_addr = inet_addr("10.0.1.1") for client accordingly.
But I am still having the problem of sending messages from one computer to another.
Here is the code:
/////////////////////Client Code///////////////////////////////
#pragma comment(lib,"ws2_32.lib")
#pragma warning(disable:4996)
#include <WinSock2.h>
#include <iostream>
int main()
{
//Winsock Startup
WSAData wsaData;
WORD DllVersion = MAKEWORD(2, 1);
if (WSAStartup(DllVersion, &wsaData) != 0) //If WSAStartup returns anything other than 0, then that means an error has occured in the WinSock Startup.
{
MessageBoxA(NULL, "Winsock startup failed", "Error", MB_OK | MB_ICONERROR);
exit(1);
}
SOCKADDR_IN addr; //Address to be binded to our Connection socket
int sizeofaddr = sizeof(addr); //Need sizeofaddr for the connect function
addr.sin_addr.s_addr = inet_addr("10.0.1.1");
addr.sin_port = htons(139); //Port = 139
addr.sin_family = AF_INET; //IPv4 Socket
SOCKET Connection = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //Set Connection socket
if (connect(Connection, (SOCKADDR*)&addr, sizeofaddr) != 0) //If we are unable to connect...
{
MessageBoxA(NULL, "Failed to Connect", "Error", MB_OK | MB_ICONERROR);
return 0; //Failed to Connect
}
std::cout << "Connected!" << std::endl;
int rec = 0;
char MOTD[256];
while (1)
{
recv(Connection, MOTD, sizeof(MOTD), NULL); //Receive Message of the Day buffer into MOTD array
std::cout << "MOTD:" << MOTD << std::endl;
std::cout << "rec:" << rec << std::endl;
rec++;
Sleep(500);
}
}
/////////////////////Server Code///////////////////////////////
#pragma comment(lib,"ws2_32.lib")
#pragma warning(disable:4996)
#include <WinSock2.h>
#include <iostream>
int main()
{
//WinSock Startup
WSAData wsaData;
WORD DllVersion = MAKEWORD(2, 1);
if (WSAStartup(DllVersion, &wsaData) != 0) //If WSAStartup returns anything other than 0, then that means an error has occured in the WinSock Startup.
{
MessageBoxA(NULL, "WinSock startup failed", "Error", MB_OK | MB_ICONERROR);
return 0;
}
SOCKADDR_IN addr; //Address that we will bind our listening socket to
int addrlen = sizeof(addr); //length of the address (required for accept call)
addr.sin_addr.s_addr = inet_addr("10.0.1.2");
addr.sin_port = htons(139); //Port
addr.sin_family = AF_INET; //IPv4 Socket
SOCKET sListen = socket(AF_INET, SOCK_STREAM, NULL); //Create socket to listen for new connections
bind(sListen, (SOCKADDR*)&addr, sizeof(addr)); //Bind the address to the socket
listen(sListen, SOMAXCONN); //Places sListen socket in a state in which it is listening for an incoming connection. Note:SOMAXCONN = Socket Oustanding Max Connections
int counter = 0;
SOCKET newConnection; //Socket to hold the client's connection
newConnection = accept(sListen, (SOCKADDR*)&addr, &addrlen); //Accept a new connection
if (newConnection == 0) //If accepting the client connection failed
{
std::cout << "Failed to accept the client's connection." << std::endl;
}
else //If client connection properly accepted
{
std::cout << "Client Connected!" << std::endl;
while (counter <100)
{
char MD[256] = "Hi there."; //Create buffer with message
send(newConnection, MD, sizeof(MD), NULL); //Send MD buffer
counter++;
}
}
system("pause");
return 0;
}
I really don't know what to do now. I can ping from one computer to another, but I can not make it work to send a message from one computer to another via the Ethernet connection.
The main problem is that the client is connecting to the wrong IP. The server's IP is 10.0.1.2, but the client is trying to connect to 10.0.1.1 instead. That is why it doesn't work across multiple computers. The client needs to connect to the server's IP, not the client's IP.
Also, you are making several other mistakes in general.
On the server side, you are ignoring the return values of bind() and listen(), and accept() returns INVALID_SOCKET (-1) on error instead of 0.
On the client side, you are ignoring the return value of recv(). It returns -1 on error, 0 on graceful disconnect, and > 0 for the number of bytes actually read. You need to pay attention to that, especially when you are sending the read data to std::cout. You are passing a char[] to operator<<, so the data must be null-terminated, but recv() does not do guarantee that. So, either:
add a null terminator to the end of the char[] data after reading it:
int numRead = recv(Connection, MOTD, sizeof(MOTD)-1, NULL);
if (numRead <= 0) break;
MOTD[numRead] = 0; // <-- here
std::cout << "MOTD:" << MOTD << std::endl;
pass the char[] to std::cin.write() instead of operator<<, specifying the actual number of bytes read in the count parameter:
int numRead = recv(Connection, MOTD, sizeof(MOTD), NULL);
if (numRead <= 0) break;
std::cout << "MOTD:";
std::cout.write(MOTD, numRead); // <-- here
std::cout << std::endl;
And your MOTD protocol is not very well designed in general. The server is sending 256 bytes (if you are lucky, send() can send fewer bytes!) for every message, even though only 9 bytes are actually being used. So you are wasting bandwidth. The client is expecting to receive exactly 256 bytes every time (which is not guaranteed, as recv() may receive fewer bytes!). A better design is to have the server send strings that have a terminating delimiter at the end, such as a line break or a null terminator, and then have the client read in a loop until it receives that delimiter, THEN process the data that has been received.
Try something more like this:
/////////////////////Client Code///////////////////////////////
#pragma comment(lib,"ws2_32.lib")
#pragma warning(disable:4996)
#include <WinSock2.h>
#include <Windows.h>
#include <iostream>
#include <string>
#include <algorithm>
int main()
{
//Winsock Startup
WSAData wsaData;
int iResult = WSAStartup(MAKEWORD(2, 1), &wsaData);
if (iResult != 0) //If WSAStartup returns anything other than 0, then that means an error has occured in the WinSock Startup.
{
std::cout << "Winsock Startup Failed, Error " << iResult << std:endl;
return 1;
}
SOCKADDR_IN addr = {};
addr.sin_family = AF_INET; //IPv4 Socket
addr.sin_addr.s_addr = inet_addr("10.0.1.2"); //Address to be connected to
addr.sin_port = htons(139); //Port = 139
SOCKET Connection = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //Create socket to establish new connection with
if (Connection == INVALID_SOCKET)
{
iResult = WSAGetLastError();
std::cout << "Failed to Create Socket, Error " << iResult << std::endl;
WSACleanup();
return 1; //Failed to Connect
}
if (connect(Connection, (SOCKADDR*)&addr, sizeof(addr)) == SOCKET_ERROR) //If we are unable to connect...
{
iResult = WSAGetLastError();
std::cout << "Failed to Connect, Error " << iResult << std::endl;
closesocket(Connection);
WSACleanup();
return 1; //Failed to Connect
}
std::cout << "Connected!" << std::endl;
int rec = 0;
char buf[256], *ptr, *start, *end;
int numRead;
std::string MOTD;
int iExitCode = 0;
while (true)
{
numRead = recv(Connection, buf, sizeof(buf), NULL); //Receive data
if (numRead == SOCKET_ERROR)
{
iResult = WSAGetLastError();
std::cout << "Failed to Read, Error " << iResult << std:endl;
iExitCode = 1;
break;
}
if (numRead == 0)
{
std::cout << "Server disconnected!" << std::endl;
break;
}
start = buf;
end = buf + numRead;
do
{
// look for MOTD terminator
ptr = std::find(start, end, '\0');
if (ptr == end)
{
// not found, need to read more...
MOTD.append(start, end-start);
break;
}
// terminator found, display current MOTD and reset for next MOTD...
MOTD.append(start, ptr-start);
std::cout << "MOTD:" << MOTD << std::endl;
std::cout << "rec:" << rec << std::endl;
rec++;
MOTD = "";
start = ptr + 1;
}
while (start < end);
}
closesocket(Connection);
WSACleanup();
return iExitCode;
}
/////////////////////Server Code///////////////////////////////
#pragma comment(lib,"ws2_32.lib")
#pragma warning(disable:4996)
#include <WinSock2.h>
#include <Windows.h>
#include <iostream>
#include <string>
bool sendAll(SOCKET s, const void *buf, int size)
{
const char *ptr = (const char*) buf;
while (size > 0)
{
int numSent = send(s, ptr, size, NULL);
if (numSent == SOCKET_ERROR) return false;
ptr += numSent;
size -= numSent;
}
return true;
}
int main()
{
//WinSock Startup
WSAData wsaData;
int iResult = WSAStartup(MAKEWORD(2, 1), &wsaData);
if (iResult != 0) //If WSAStartup returns anything other than 0, then that means an error has occured in the WinSock Startup.
{
std::cout << "WinSock Startup Failed, Error " << iResult << std::endl;
return 1;
}
SOCKADDR_IN addr = {};
addr.sin_family = AF_INET; //IPv4 Socket
addr.sin_addr.s_addr = INADDR_ANY; //Address that we will bind our listening socket to. INADDR_ANY = all local IPv4 addresses
addr.sin_port = htons(139); //Port
SOCKET sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //Create socket to listen for new connections
if (sListen == INVALID_SOCKET)
{
iResult = WSAGetLastError();
std::cout << "Failed to Create Socket, Error " << iResult << std::endl;
closesocket(sListen);
WSACleanup();
return 1;
}
if (bind(sListen, (SOCKADDR*)&addr, sizeof(addr)) == SOCKET_ERROR) //Bind the address to the socket
{
iResult = WSAGetLastError();
std::cout << "Failed to Bind Socket, Error " << iResult << std::endl;
closesocket(sListen);
WSACleanup();
return 1;
}
if (listen(sListen, SOMAXCONN) == SOCKET_ERROR) //Places sListen socket in a state in which it is listening for an incoming connection. Note:SOMAXCONN = Socket Outstanding Max Connections
{
iResult = WSAGetLastError();
std::cout << "Failed to Listen, Error " << iResult << std::endl;
closesocket(sListen);
WSACleanup();
return 1;
}
SOCKET newConnection; //Socket to hold the client's connection
int iExitCode = 0;
do
{
std::cout << "Waiting for Client to Connect..." << std::endl;
int addrlen = sizeof(addr); //length of the address (required for accept call)
newConnection = accept(sListen, (SOCKADDR*)&addr, &addrlen); //Accept a new connection
if (newConnection == INVALID_SOCKET) //If accepting the client connection failed
{
iResult = WSAGetLastError();
std::cout << "Failed to accept a client's connection, Error " << iResult << std::endl;
iExitCode = 1;
break;
}
std::cout << "Client Connected!" << std::endl;
for (int counter = 0; counter < 100; ++counter)
{
std::string MOTD = "Hi there."; //Create buffer with message
if (!sendAll(newConnection, MOTD.c_str(), MOTD.length()+1))
{
iResult = WSAGetLastError();
std::cout << "Failed to Send, Error " << iResult << std::endl;
break;
}
}
closesocket(newConnection);
std::cout << "Client Disconnected!" << std::endl;
}
while (true);
closesocket(sListen);
WSACleanup();
return iExitCode;
}
Thank you for all the answers and comments! I solved the problem via changing the port number. Apparently, some of the port numbers are reserved so I have to assign another one.
Firstly, the code I will share is the basis of my code(found it in another site, open source), I added functions and threads later to improve.
In the office, we have local network and another 3 computer cannot connect to my server. Especially have a look at that line. 26010 is random port number that I want to listen. According to data I found in the other topics, NULL and 127.0.0.1 are the localhost ip.I tried my own ip number instead of NULL, but it didn't work. I can send data from my client code to other computers, but can't get any connections.
Code is listening connections properly, and can get info if I open another 3 terminal and try to connect it from my computer through my client code. How to fix that?
Thanks in advance.
status = getaddrinfo(NULL, "26010", &host_info, &host_info_list);
int main()
{
int status;
struct addrinfo host_info; // The struct that getaddrinfo() fills up with data.
struct addrinfo *host_info_list; // Pointer to the to the linked list of host_info's.
memset(&host_info, 0, sizeof host_info);
std::cout << "Setting up the structs..." << std::endl;
host_info.ai_family = AF_UNSPEC; // IP version not specified. Can be both.
host_info.ai_socktype = SOCK_STREAM; // Use SOCK_STREAM for TCP or SOCK_DGRAM for UDP.
host_info.ai_flags = AI_PASSIVE;
**status = getaddrinfo(NULL, "26010", &host_info, &host_info_list);**
// getaddrinfo returns 0 on succes, or some other value when an error occured.
// (translated into human readable text by the gai_gai_strerror function).
if (status != 0) std::cout << "getaddrinfo error" << gai_strerror(status) ;
std::cout << "Creating a socket..." << std::endl;
int socketfd ; // The socket descripter
socketfd = socket(host_info_list->ai_family, host_info_list->ai_socktype,
host_info_list->ai_protocol);
if (socketfd == -1) std::cout << "socket error " ;
std::cout << "Binding socket..." << std::endl;
int yes = 1;
status = setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
status = bind(socketfd, host_info_list->ai_addr, host_info_list->ai_addrlen);
if (status == -1) std::cout << "bind error" << std::endl ;
std::cout << "Listen()ing for connections..." << std::endl;
status = listen(socketfd, 5);
if (status == -1) std::cout << "listen error" << std::endl ;
int new_sd;
struct sockaddr_storage their_addr;
socklen_t addr_size = sizeof(their_addr);
new_sd = accept(socketfd, (struct sockaddr *)&their_addr, &addr_size);
if (new_sd == -1)
{
std::cout << "listen error" << std::endl ;
}
else
{
std::cout << "Connection accepted. Using new socketfd : " << new_sd << std::endl;
}
std::cout << "Waiting to recieve data..." << std::endl;
ssize_t bytes_recieved;
char incomming_data_buffer[1000];
bytes_recieved = recv(new_sd, incomming_data_buffer,1000, 0);
// If no data arrives, the program will just wait here until some data arrives.
...
std::cout << "send()ing back a message..." << std::endl;
return 0 ;
}
Your problem is your call to getaddrinfo(). This function returns information in the host_info_list member. What you're reading is the hint (host_info) which is not changed by getaddrinfo(). You would need to use host_info_list to read the what's returned by getaddrinfo. You never use it and you never free it (by calling freeaddrinfo).
I am not sure why you'd want to use getaddrinfo() to listen for connection. You can just build the sockaddr yourself. It's easy:
struct sockaddr_in listenAddr;
memset(&listenAddr, 0, sizeof(listenAddr));
/* IPv4 address */
listenAddr.sin_family = AF_INET;
/* your port number */
listenAddr.sin_port = htons(26010);
/* listen on all interfaces */
listenAddr.sin_addr.s_addr = htonl(INADDR_ANY);
/* TCP socket */
socketfd = socket(PF_INET, SOCK_STREAM, 0);
/* your error code, omitted here */
status = bind(SocketFD,(struct sockaddr *) &listenAddr, sizeof(listenAddr))
Hello i am a beginner socket/c programmer and from this tutorial i have the connect function returns 10038 error. please help. what am i doing wrong?
also whats the difference between winsock and winsock2?
also in connect() function definition there is int PASCAL
what is pascal for?
#include <iostream>
#include <winsock.h>
using namespace std;
int main(){
WSADATA wsa;
cout<< "Iinitializing winsock....";
SOCKET sa;
struct sockaddr_in server;
if (WSAStartup(MAKEWORD(2,2), &wsa)!=0)
cout << "Failed";
cout << "initialized";
if ((sa = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) == INVALID_SOCKET))
cout << "Could not create socket " << WSAGetLastError();
cout << "Socket created";
server.sin_addr.s_addr = inet_addr ("213.165.64.44");
server.sin_family = AF_INET;
server.sin_port = htons(7);
//connect
if (connect(sa, (struct sockaddr *)&server, sizeof(server)) < 0){
cerr << "connect error" << WSAGetLastError();
return 1;
}
cout << "connected";
return 0;
}
You should look at the documentation what 10038 means:
WSAENOTSOCK
10038 (0x2736)
An operation was attempted on something that is not a socket.
So sa is not a socket. Printing out sa to cerr shows that it is zero, so something around the call to the socket() function is bad. Looking at the line more closely reveals that there is a parentheses error in the line:
if ((sa = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) == INVALID_SOCKET))
the == is executed first, and as the return value of the socket() function is not invalid socket, zero gets assigned to sa.
The correct expression would be:
if ((sa = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
For the other parts of the question:
winsock (winsock.dll) is v1.1 of the API, winsock2 (ws2_32.dll) is the second version that has many improvements. As it is part of Windows since Win98 (and downloadable for Win95), I'd recommend using at least winsock2.
PASCAL is a macro for __stdcall˙, Windows API functions generally use this calling convention.