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.
Related
So, I was trying to code this simple TCP server, but I'm stucked with this error
error: 'inet_ntop' was not declared in this scope; did you mean 'inet_ntoa'
I know that I have to use ntop and not ntoa. But I can't find out how to get rid of this error. I searched everywhere and couldn't find anything. I hope someone can help me. My code is below.
#define _WIN32_WINNT 0x501
#include <iostream>
#include <WS2tcpip.h>
#pragma comment (lib, "ws2_32.lib")
using namespace std;
int main(void){
//initialize winsock
WSADATA WSData;
WORD ver = MAKEWORD(2, 2);
int WSOK = WSAStartup(ver, &WSData);
if (WSOK != 0){
cerr << "Can't initialize winsock! Quitting" << endl;
return 0;
}
//create a socket
SOCKET listening = socket(AF_INET, SOCK_STREAM, 0);
if (listening == INVALID_SOCKET)
{
cerr << "Can't create a socket! Quitting" << endl;
return 0;
}
// bind the socket to an ip adress an port to a socket
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(54000);
hint.sin_addr.S_un.S_addr = INADDR_ANY; // could also use inet_pton...
bind(listening, (sockaddr*)&hint, sizeof(hint));
//tell winsock the socket is for listening
listen(listening, SOMAXCONN);
//wait for connection
sockaddr_in client;
int clientSize = sizeof(client);
SOCKET clientSocket = accept(listening, (sockaddr*)&client, &clientSize);
char host[NI_MAXHOST]; // client's remote name
char service[NI_MAXSERV]; // Service (i.e port) the client is connected on
ZeroMemory(host, NI_MAXHOST);
ZeroMemory(service, NI_MAXSERV);
if (getnameinfo((sockaddr*)&client, sizeof(client), host, NI_MAXHOST, service, NI_MAXSERV, 0) == 0)
{
cout << host << "connected on port" << service << endl;
}
else
{
inet_ntop(AF_INET, &client.sin_addr), host, NI_MAXHOST);
cout << host << "connecte on port" <<
ntohs(client.sin_port) << endl;
}
//close listening socket
closesocket(listening);
//while loop: accept and echo message bac to client
char buf[4096];
while (true)
{
ZeroMemory(buf, 4096);
//wait for client send data
int bytesReceived = recv(clientSocket, buf, 4096, 0);
if (bytesReceived == SOCKET_ERROR)
{
cerr << "Error in recv(). Quitting" << endl;
break;
}
if (bytesReceived == 0)
{
cout << "Client disconnected " << endl;
break;
}
//echo message back to client
send(clientSocket, buf, bytesReceived + 1, 0);
}
//close socket
closesocket(clientSocket);
// cleanup winsock
WSACleanup();
}
inet_ntop() requires Windows Vista and later at runtime, but you are setting _WIN32_WINNT to 0x501, which represents Windows XP, so the declaration of inet_ntop() in <w32tcpip.h> gets disabled at compile-time to prevent the program from failing to start at runtime.
You need to set _WIN32_WINNT to at least 0x600 instead to enable inet_ntop().
However, even after you fix that issue, your code will still fail to compile, because you have a syntax mistake in your call to inet_ntop() - your parenthesis are unbalanced in the 2nd parameter. You have either a missing (, or an erroneous ), depending on which of the following syntaxes you were trying to use:
inet_ntop(AF_INET, &(client.sin_addr), host, NI_MAXHOST);
inet inet_ntop(AF_INET, &client.sin_addr, host, NI_MAXHOST);
You also have other logic errors that won’t show up until runtime. You are not doing any error handling on bind(), listen(), and send(). And you have a potential buffer overflow on send(), too.
I created a simple code to connect to a Gmail SMTP server, but the function connect() returns -1 (SOCKET_ERROR). What's wrong with this code?
#include <iostream>
#include <winsock2.h>
#include <ws2tcpip.h>
int main()
{
WSADATA wsaData;
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("smtp.gmail.com");
addr.sin_port = htons(587);
//WSA STARTUP
if (WSAStartup(MAKEWORD(2, 2), &wsaData))
{
std::cout << "Failed to startup wsa.\n";
return 1;
}
// GNIAZDO DLA KLIENTA
SOCKET mSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (mSocket == INVALID_SOCKET)
{
std::cout << "Socket error: " << WSAGetLastError();
WSACleanup();
return 1;
}
//LACZENIE Z SERWEREM
int status = connect(mSocket, (SOCKADDR*)&addr, sizeof(addr));
std::cout << "Connection status: " << status;
return 0;
}
inet_addr expects an IP address in dot notation, as in "1.2.3.4". It does not resolve domain names. You are looking for getaddrinfo
The answer below is correct, but since you are using Windows, an easier option is WSAConnectByName which avoids all the old-fashioned htons/getaddrinfo stuff and also works with IPv6 automatically.
I created TCP socket connection between client and server.
It is necessary for me to use threads because I'm getting x and y coordinates from another process, and drawing those values with OpenGL.
Only way I had in mind was to create thread for OpenGL drawing, and use main thread to recieve coordinates by socket.
My server side worked perfectly before adding #include <thread>, so I have no idea what could the problem be and why couldn't I use threads while using sockets.
After including thread, after calling recv(), I'm getting error:
WSAENOTSOCK 10038
by using WSAGetLastError();
I think that code is too long for me to post it so I can copy some parts of it that are necessary.
EDIT: code of creating socket and waiting for connection.
// Inicijaliziraj winsock
WSADATA wsData;
WORD ver = MAKEWORD(2, 2);
int wSocket = WSAStartup(ver, &wsData);
if (wSocket != 0) {
cerr << "Problem with initialization of Winsock, exiting!" << endl;
return;
}
// Create a socket
SOCKET listening = socket(AF_INET, SOCK_STREAM, 0);
if (listening == INVALID_SOCKET) {
cerr << "Unable to create a socket! Quitting" << endl;
return;
}
// Bind the ip address and port to a socket
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(54000);
hint.sin_addr.S_un.S_addr = INADDR_ANY; // Could also use inet_pton
bind(listening, (sockaddr*)&hint, sizeof(hint));
// Tell winsock socket is for listening
listen(listening, SOMAXCONN);
// Wait for a connection
sockaddr_in client;
int clientSize = sizeof(client);
SOCKET clientSocket = accept(listening, (sockaddr*)&client, &clientSize);
/*
if (clientSocket == INVALID_SOCKET) {
cerr << "Unable to connect to client socket, Quitting!" << endl;
return;
}*/
char host[NI_MAXHOST]; // Client's remote name
char service[NI_MAXHOST]; // Service (PORT) the client is connected on
ZeroMemory(host, NI_MAXHOST); // Could use memset(host, 0, )
ZeroMemory(service, NI_MAXHOST);
if (getnameinfo((sockaddr*)&client, sizeof(client), host, NI_MAXHOST, service, NI_MAXSERV, 0) == 0)
{
cout << host << " connected on port " << service << endl;
}
else
{
inet_ntop(AF_INET, &client.sin_addr, host, NI_MAXHOST);
cout << host << " connected on port " << ntohs(client.sin_port) << endl;
}
// Close listening socket
closesocket(listening);
// While loop: accept and echo message back to client
char buf[4096];
//Opens new thread with canvas because otherwise while loop for recieving will block drawing
//std::thread t1(setDrawing, &iArgc, cppArgv);
while (true) {
ZeroMemory(buf, 4096);
// Wait for client to send data
int bytesRecieved = recv(clientSocket, buf, 4096, 0);
if (bytesRecieved == SOCKET_ERROR) {
int err = WSAGetLastError();
cerr << "Error in recv(). Quitting!" << endl;
break;
}
if (bytesRecieved == 0) {
cout << "Client disconnected " << endl;
break;
}
My server side worked perfectly before adding #include <thread>, so I have no idea what could the problem be and why couldn't I use threads while using sockets.
One thing to pay attention to is that <thread> is a C++ STL header. If your code happens to have a using namespace std; statement, your socket code may end up calling the STL's std::bind() function instead of WinSock's bind() function, which would in turn cause listen() to fail with an WSAEINVAL error. Which you are not checking for since you are not doing any error handling on your bind() or listen() calls. So be aware of that. Avoid using namespace std; statements, or call WinSock's bind() as ::bind() instead. And ALWAYS do error handling on API calls.
You have also commented out your error handling on accept(). If bind() and listen() fail, so will accept(), causing it to return INVALID_SOCKET. Which could explain why you are then getting the WSAENOTSOCK error on recv().
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.
I'm trying to write a simple program that will receive a string of max 20 characters and print that string to the screen.
The code compiles, but I get a bind() failed: 10038. After looking up the error number on msdn (socket operation on nonsocket), I changed some code from
int sock;
to
SOCKET sock
which shouldn't make a difference, but one never knows.
Here's the code:
#include <iostream>
#include <winsock2.h>
#include <cstdlib>
using namespace std;
const int MAXPENDING = 5;
const int MAX_LENGTH = 20;
void DieWithError(char *errorMessage);
int main(int argc, char **argv)
{
if(argc!=2){
cerr << "Usage: " << argv[0] << " <Port>" << endl;
exit(1);
}
// start winsock2 library
WSAData wsaData;
if(WSAStartup(MAKEWORD(2,0), &wsaData)!=0){
cerr << "WSAStartup() failed" << endl;
exit(1);
}
// create socket for incoming connections
SOCKET servSock;
if(servSock=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)==INVALID_SOCKET)
DieWithError("socket() failed");
// construct local address structure
struct sockaddr_in servAddr;
memset(&servAddr, 0, sizeof(servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = INADDR_ANY;
servAddr.sin_port = htons(atoi(argv[1]));
// bind to the local address
int servAddrLen = sizeof(servAddr);
if(bind(servSock, (SOCKADDR*)&servAddr, servAddrLen)==SOCKET_ERROR)
DieWithError("bind() failed");
// mark the socket to listen for incoming connections
if(listen(servSock, MAXPENDING)<0)
DieWithError("listen() failed");
// accept incoming connections
int clientSock;
struct sockaddr_in clientAddr;
char buffer[MAX_LENGTH];
int recvMsgSize;
int clientAddrLen = sizeof(clientAddr);
for(;;){
// wait for a client to connect
if((clientSock=accept(servSock, (sockaddr*)&clientAddr, &clientAddrLen))<0)
DieWithError("accept() failed");
// clientSock is connected to a client
// BEGIN Handle client
cout << "Handling client " << inet_ntoa(clientAddr.sin_addr) << endl;
if((recvMsgSize = recv(clientSock, buffer, MAX_LENGTH, 0)) <0)
DieWithError("recv() failed");
cout << "Word in the tubes: " << buffer << endl;
closesocket(clientSock);
// END Handle client
}
}
void DieWithError(char *errorMessage)
{
fprintf(stderr, "%s: %d\n", errorMessage, WSAGetLastError());
exit(1);
}
The problem is with
servSock=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)==INVALID_SOCKET
which does not associate as you think it does. Why would you even want to write something like that, what's wrong with
SOCKET servSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(servSock == INVALID_SOCKET)
DieWithError("socket() failed");
?