I'm beginner in winsock programming and i witnessed a peculiar behaviour of the connect function to establish a socket connection.The socket function succeeds even though there's no valid host in the network .For example there's no host with the ip 192.168.4.28 in our network but the connection to the call still succeeds and i tried giving ip address that's outside our network for example 1.1.1.1 and it still succeeded . Is there a reason or there's a bug in the api.i have used the code in the msdn site provided in this
http://msdn.microsoft.com/en-us/library/windows/desktop/ms737625(v=vs.85).aspx .
CODE
#ifndef UNICODE
#define UNICODE
#endif
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib")
int main()
{
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR) {
wprintf(L"WSAStartup function failed with error: %d\n", iResult);
return 1;
}
SOCKET ConnectSocket;
ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ConnectSocket == INVALID_SOCKET) {
wprintf(L"socket function failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
sockaddr_in clientService;
clientService.sin_family = AF_INET;
clientService.sin_addr.s_addr = inet_addr("192.168.4.28"); //No Host by this ip address
clientService.sin_port = htons(80); //Port is 80
iResult = connect(ConnectSocket, (SOCKADDR *) & clientService, sizeof (clientService));
printf("The socket connect return status : %d ",iResult); // always 0 , indicating success
if (iResult == SOCKET_ERROR) {
wprintf(L"connect function failed with error: %ld\n", WSAGetLastError());
iResult = closesocket(ConnectSocket);
if (iResult == SOCKET_ERROR)
wprintf(L"closesocket function failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
wprintf(L"Connected to server.\n");
iResult = closesocket(ConnectSocket);
if (iResult == SOCKET_ERROR) {
printf("\n socket Connection failed ");
WSACleanup();
return 1;
}
WSACleanup();
return 0;
}
Related
I am trying to implement a client-server architecture using sockets in Windows with winsock.h. When I call bind() function I get the error code 10038 and I don`t know why.
Here it is my code. This is only the server, created inside a thread where I initialice the socket and jump into an infinite loop to read data from client usng recvfrom function.
typedef struct
{
int sockfd;
struct sockaddr_in dir_client;
int long_dir_client;
struct sockaddr_in dir_server;
uint32_t receive_data;
}server_t;
void RX_thread_Client(void)
{
WSADATA wsaData;
server_t server;
int iResult;
int BytesReceived;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("[RxThreadClient] WSAStartup failed with error: %d\n", iResult);
return;
}
memset((char*)& server.dir_server, 0, sizeof(server.dir_server));
server.dir_server.sin_family = AF_INET;
server.dir_server.sin_addr.s_addr = inet_addr("10.128.169.46");
server.dir_server.sin_port = htons(6500);
server.long_dir_client = sizeof(server.dir_client);
// Create a new socket to make a client connection.
// AF_INET = 2, The Internet Protocol version 4 (IPv4) address family, TCP protocol
if ( server.sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP) == INVALID_SOCKET)
{
printf("[RxThreadClient] Client: socket() failed! Error code: %ld\n", WSAGetLastError());
// Do the clean up
WSACleanup();
// Exit with error
return;
}
else
printf("[RxThreadClient] Client: socket() is OK!\n");
if ( bind(server.sockfd, (struct sockaddr*)&server.dir_server, sizeof(server.dir_server)) < 0) // ERROR IS HERE!!!
{
printf("[RxThreadClient] bind() failed! Error code: %ld\n", WSAGetLastError());
return;
}
else
printf("[RxThreadClient] Client: bind() is OK!\n");
while (1)
{
BytesReceived = recvfrom (server.sockfd, (char*)&server.receive_data,
sizeof(server.receive_data), 0,
(struct sockaddr*) & server.dir_client,
&server.long_dir_client);
if (BytesReceived == SOCKET_ERROR)
{
printf("[RxThreadClient] Client: send() error %ld.\n", WSAGetLastError());
break;
}
else
{
printf("[RxThreadClient] Client: send() is OK - bytes received: %ld\n", BytesReceived);
printf("[RxThreadClient] Word received: %d\n", server.receive_data);
}
Sleep(1000);
}
}
Thank you very much
I'm learning winsock programming. I have a question about the code provided in msdn: https://learn.microsoft.com/en-us/windows/desktop/winsock/complete-client-code
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
// 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")
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "27015"
int __cdecl main(int argc, char **argv)
{
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
char *sendbuf = "this is a test";
char recvbuf[DEFAULT_BUFLEN];
int iResult;
int recvbuflen = DEFAULT_BUFLEN;
// Validate the parameters
if (argc != 2) {
printf("usage: %s server-name\n", argv[0]);
return 1;
}
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory( &hints, sizeof(hints) );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
iResult = getaddrinfo(argv[1], DEFAULT_PORT, &hints, &result);
if ( iResult != 0 ) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// Attempt to connect to an address until one succeeds
for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {
// Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
// Connect to server.
iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
break;
}
freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET) {
printf("Unable to connect to server!\n");
WSACleanup();
return 1;
}
// Send an initial buffer
iResult = send( ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 );
if (iResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
printf("Bytes Sent: %ld\n", iResult);
// shutdown the connection since no more data will be sent
iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
// Receive until the peer closes the connection
do {
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
if ( iResult > 0 )
printf("Bytes received: %d\n", iResult);
else if ( iResult == 0 )
printf("Connection closed\n");
else
printf("recv failed with error: %d\n", WSAGetLastError());
} while( iResult > 0 );
// cleanup
closesocket(ConnectSocket);
WSACleanup();
return 0;
}
Why the client have to use a loop with socket() and connect(), the Linux version of the program doesn't need it. Can I remove it? or is it implementation-dependency ?
Such a loop is common when using getaddrinfo (even on Linux).
The getaddrinfo function can return a list with multiple possible remote addresses, or multiple address families, or multiple protocols. The loop tries all of the addresses in the list until it successfully connects.
I'm just confusing using the send() function in Winsock. Does this code actually send a string "Hello" over TCP ?. I managed to establish a connection with a TCP client in LabVIEW but it seems like that this TCP server doesn't send anything.
#define DEFAULT_BUFLEN 1024
#include<stdio.h>
#include<winsock2.h>
#include<Ws2tcpip.h>
#include<stdlib.h>
#include<string.h>
#include<stdint.h>
#include<stddef.h>
#pragma comment(lib,"ws2_32.lib") //Winsock Library
int main(int argc , char *argv[])
{
WSADATA wsa;
SOCKET s , new_socket;
struct sockaddr_in server , client;
int c;
int iResult;
char *sendbuf = "Hello";
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
{
printf("Failed. Error Code : %d",WSAGetLastError());
return 1;
}
printf("Initialised.\n");
//Create a socket
if((s = socket(AF_INET , SOCK_STREAM , 0 )) == INVALID_SOCKET)
{
printf("Could not create socket : %d" , WSAGetLastError());
}
printf("Socket created.\n");
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 13000 );
//Bind
if( bind(s ,(struct sockaddr *)&server , sizeof(server)) == SOCKET_ERROR)
{
printf("Bind failed with error code : %d" , WSAGetLastError());
}
puts("Bind done");
//Listen to incoming connections
listen(s , 3);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
new_socket = accept(s , (struct sockaddr *)&client, &c);
if (new_socket == INVALID_SOCKET)
{
printf("accept failed with error code : %d" , WSAGetLastError());
}
iResult = send( new_socket, sendbuf, (int)strlen(sendbuf), 0 );
if (iResult == SOCKET_ERROR)
{
wprintf(L"send failed with error: %d\n", WSAGetLastError());
closesocket(new_socket);
WSACleanup();
return 1;
}
printf("Bytes Sent: %d\n", iResult);
// shutdown the connection since no more data will be sent
iResult = shutdown(new_socket, SD_SEND);
if (iResult == SOCKET_ERROR)
{
wprintf(L"shutdown failed with error: %d\n", WSAGetLastError());
closesocket(new_socket);
WSACleanup();
return 1;
}
}
Your code is not initialzing WinSock, not allocating any SOCKET object, and not establishing a connection between the socket and a peer before calling send(), so to answer your question:
NO, your code is NOT sending a string over TCP.
HOWEVER, if you fill in the missing pieces - call socket() to create a TCP socket, and call bind()/listen()/accept() to establish a TCP connection with a peer - then YES, your code will be sending the string over TCP.
You need to do something more like the following instead. This is just a simple example that establishes a single TCP connection and then exits once the string has been sent to the client. In a real-world application, you would need to leave the server socket open and continuously calling accept() if you want to service multiple client connections over time, even if just a single client ever connects, disconnects, and reconnects:
int main(int argc , char *argv[])
{
WSADATA wsa;
SOCKET server_socket, client_socket;
struct sockaddr_in server_addr, client_addr;
int iResult;
char *sendbuf = "Hello";
iResult = WSAStartup(MAKEWORD(2, 0), &wsa);
if (iResult != 0)
{
wprintf(L"WinSock startup failed with error: %d\n", iResult);
return 1;
}
server_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (server_socket == INVALID_SOCKET)
{
wprintf(L"socket failed with error: %d\n", WSAGetLastError());
WSACleanup();
return 1;
}
memset(&server_addr, 0, sizeof(server_addr);
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(some port number here);
server_addr.sin_addr.s_addr = INADDR_ANY;
if (bind(server_socket, (sockaddr*)&server_addr, sizeof(server_addr)) != 0)
{
wprintf(L"bind failed with error: %d\n", WSAGetLastError());
closesocket(server_socket);
WSACleanup();
return 1;
}
if (listen(server_socket, 1) != 0)
{
wprintf(L"listen failed with error: %d\n", WSAGetLastError());
closesocket(server_socket);
WSACleanup();
return 1;
}
iResult = sizeof(client_addr);
client_socket = accept(server_socket, (sockaddr*)&client_addr, &iResult);
if (client_socket == SOCKET_ERROR)
{
wprintf(L"accept failed with error: %d\n", WSAGetLastError());
closesocket(server_socket);
WSACleanup();
return 1;
}
closesocket(server_socket);
iResult = send(client_socket, sendbuf, strlen(sendbuf), 0);
if (iResult == SOCKET_ERROR)
{
wprintf(L"send failed with error: %d\n", WSAGetLastError());
closesocket(client_socket);
WSACleanup();
return 1;
}
printf("Bytes Sent: %d\n", iResult);
closesocket(client_socket);
WSACleanup();
return 0;
}
Update: based on your updated code, try this:
#include <stdio.h>
#include <winsock2.h>
#include <Ws2tcpip.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stddef.h>
#pragma comment(lib, "ws2_32.lib") //Winsock Library
int main(int argc , char *argv[])
{
WSADATA wsa;
SOCKET server_socket, client_socket;
struct sockaddr_in server_addr, client_addr;
int c, iResult;
char *sendbuf = "Hello";
printf("Initializing Winsock...\n");
iResult = WSAStartup(MAKEWORD(2,2), &wsa);
if (iResult != 0)
{
printf("WinSock initialization Failed. Error Code : %d", iResult);
return 1;
}
printf("WinSock Initialized.\n");
//Create a socket
s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s == INVALID_SOCKET)
{
printf("Could not create socket. Error Code : %d" , WSAGetLastError());
WSACleanup();
return 1;
}
printf("Socket created.\n");
//Prepare the sockaddr_in structure
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons( 13000 );
//Bind the listening port
if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == SOCKET_ERROR)
{
printf("Bind failed. Error Code : %d", WSAGetLastError());
closesocket(server_socket);
WSACleanup();
return 1;
}
printf("Socket bound to port 13000.\n");
//Listen to incoming connection
if (listen(server_socket, 1) == SOCKET_ERROR)
{
printf("Listen failed. Error Code : %d", WSAGetLastError());
closesocket(server_socket);
WSACleanup();
return 1;
}
//Accept an incoming connection
printf("Waiting for incoming connection...\n");
c = sizeof(client_addr);
client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &c);
if (client_socket == INVALID_SOCKET)
{
printf("Accept failed. Error Code : %d", WSAGetLastError());
closesocket(server_socket);
WSACleanup();
return 1;
}
printf("Client connected from %s:%hu\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
//Stop accepting incoming connections
closesocket(server_socket);
// Send string to client
iResult = send(client_socket, sendbuf, strlen(sendbuf), 0);
if (iResult == SOCKET_ERROR)
{
printf("Send failed. Error Code : %d\n", WSAGetLastError());
iResult = 1;
}
else
{
printf("Bytes Sent: %d\n", iResult);
iResult = 0;
}
// shutdown the connection since no more data will be sent
if (shutdown(client_socket, SD_SEND) == SOCKET_ERROR)
{
printf("Shutdown failed. Error Code : %d\n", WSAGetLastError());
iResult = 1;
}
closesocket(client_socket);
WSACleanup();
return iResult;
}
No, it does not send the string "Hello". Even if the socket bind/accept/etc connection is OK, 'send(client_socket, sendbuf, strlen(sendbuf), 0);' does not send a C string. It sends five bytes, whereas the the C string "Hello" requires six bytes. Try:
send(client_socket, sendbuf, 1+strlen(sendbuf), 0);
A very high percentage of networking C code problems can be found by searching the source text for 'strlen'. printf(%s..), and assuming that TCP transfers messages longer than one byte, accounts for the rest:)
I'm writing a code to discover the devices on the network and this is just a part of it.
I'm trying to discover a host by establishing an socket connection with the host on port 80.
It connects well on some of the hosts on port 80 as the devices are listening on port 80. At times the connect function returns error as WSACONNECTIONREFUSED as there is no web service running on the host.
It is surprising to see that when i try to establish an socket connection on invalid ip addresses I get WSACONNECTIONREFUSED instead of WSAETIMEDOUT.
I googled and found out that the antivirus and firewall can cause the problems and i have disabled both on the scanning machine but no luck what could be causing the problem?
I have posted the code below:
#ifndef UNICODE
#define UNICODE
#endif
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib")
int main()
{
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR)
{
wprintf(L"WSAStartup function failed with error: %d\n", iResult);
return 1;
}
SOCKET ConnectSocket;
ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ConnectSocket == INVALID_SOCKET)
{
wprintf(L"socket function failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
sockaddr_in clientService;
clientService.sin_family = AF_INET;
clientService.sin_addr.s_addr = inet_addr("192.168.4.28"); //No Host by this ip address
clientService.sin_port = htons(80); //Port is 80
iResult = connect(ConnectSocket, (SOCKADDR *) &clientService,
sizeof(clientService));
printf("The socket connect return status : %d ", iResult);
if (iResult == SOCKET_ERROR)
{
wprintf(L"connect function failed with error: %ld\n", WSAGetLastError());
iResult = closesocket(ConnectSocket);
if (iResult == SOCKET_ERROR)
wprintf(L"closesocket function failed with error: %ld\n",
WSAGetLastError());
WSACleanup();
return 1;
}
wprintf(L"Connected to server.\n");
iResult = closesocket(ConnectSocket);
if (iResult == SOCKET_ERROR)
{
printf("\n socket Connection failed ");
WSACleanup();
return 1;
}
WSACleanup();
return 0;
}
Below is the code, I took from MSDN's tutorial examples for Winsock server programming. The code seems to be working fine. When I type http://localhost:27015 in my browser, the code responds appropriately. However, I am unable to work with the string sent by the browser as request and stored here as character array in recvbuf. For example, I am not able to printf the buffer or use fwrite either. The program terminates immediately. Please help.
#undef UNICODE
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
// Need to link with Ws2_32.lib
#pragma comment (lib, "Ws2_32.lib")
// #pragma comment (lib, "Mswsock.lib")
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "27015"
int __cdecl main(void)
{
WSADATA wsaData;
SOCKET ListenSocket = INVALID_SOCKET,
ClientSocket = INVALID_SOCKET;
struct addrinfo *result = NULL,
hints;
char recvbuf[DEFAULT_BUFLEN];
char *sendbuf = "HTTP/1.1 200 OK \r\n Date: Fri, 31 Dec 1999 23:59:59 GMT \r\n Content- Type: text/html\r\n";
int iResult, iSendResult;
int recvbuflen = DEFAULT_BUFLEN;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
else
printf("\nInitialising winsock...done");
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
// Resolve the server address and port
iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
if ( iResult != 0 ) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
else
printf("\nResolving server address...done");
//localhost:27015/
// Create a SOCKET for connecting to server
ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (ListenSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return 1;
}
else
printf("\nCreating connection socket...done");
// Setup the TCP listening socket
iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR) {
printf("bind failed with error: %d\n", WSAGetLastError());
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
return 1;
}
else
printf("\nCreating listening socket...done");
printf("\nWaiting for connection... ");
freeaddrinfo(result);
iResult = listen(ListenSocket, SOMAXCONN);
if (iResult == SOCKET_ERROR) {
printf("listen failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
// Accept a client socket
ClientSocket = accept(ListenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET) {
printf("accept failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
// No longer need server socket
closesocket(ListenSocket);
// Receive until the peer shuts down the connection
do
{
iResult = recv(ClientSocket, recvbuf, recvbuflen,0);
if (iResult > 0) {
printf("Bytes received: %d\n", iResult);
// Echo the buffer back to the sender
iSendResult = send(ClientSocket,sendbuf,(int)strlen(sendbuf), 0 );
if (iSendResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
printf("Bytes sent: %d\n", iSendResult);
}
else if (iResult == 0)
printf("Connection closing...\n");
else {
printf("recv failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
}while(iResult>0);
// shutdown the connection since we're done
iResult = shutdown(ClientSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
// cleanup
closesocket(ClientSocket);
WSACleanup();
//Appended later
printf("\n");
int i =0;
while(i<120)
{
printf("%c",recvbuf[i]);
++i;
}
return 0;
}
Thanks!
iResult = recv(ClientSocket, recvbuf, recvbuflen,0);
In the above, the data received through recv() is not zero-terminated. iResult is the length of the data, to output it as text:
printf("%.*s", iResult, recvbuf);
Adding the following function helped. The hint was already provided by Maxim when he said
data received through recv() is not
zero-terminated.
void handleBuffer()
{
recvbuf[DEFAULT_BUFLEN-1]='\0';
printf("*********************\n");
printf("%s",recvbuf);
}
I also increased my DEFAULT_BUFLEN to 4096. Call the function to print the output anytime.