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
Hai friends I am a newbie learning winsock2. the following is my udp server and client programs.
I this program the client does not know the ip address of the server but knows only the port. But the server broadcasts a message all over the network.
when the client gets the message it traces back the ip of the server and connects to it.
Both my server and client show no error while compiling.
But while Executing the client's recvfrom() statement shows error
the following are the part of my code.
SERVER CODE:
#include "stdafx.h"
#include<stdio.h>
#include<WinSock2.h>
#pragma comment (lib,"ws2_32.lib")
DWORD WINAPI UDPCONN(LPVOID x)
{
SOCKET s=(SOCKET)x;
char bro[200]="I am SERVER";
struct sockaddr_in hum;
hum.sin_family=AF_INET;
hum.sin_addr.s_addr=INADDR_BROADCAST;
hum.sin_port=htons(8888);
while (1)
{
if(sendto(s,bro,sizeof(bro),0,(struct sockaddr *)&hum,sizeof(hum))==SOCKET_ERROR)
{
printf("\nBroadcast failed ERROR CODE : %d\n",WSAGetLastError());
exit(1);
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
SOCKET s;
struct sockaddr_in hum;
int opt=1;
//Initializing winsock2
WSADATA wsa;
if((WSAStartup(MAKEWORD(2,2),&wsa))!=0)
{
printf("\nWinsock Not initialized ERROR CODE : %d\n",WSAGetLastError());
return 1;
}
//UDP Socket Creation
if((s=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP))==INVALID_SOCKET)
{
printf("\nUDP Socket not created ERROR CODE : %d\n",WSAGetLastError());
WSACleanup();
return 1;
}
//socket defenition
hum.sin_family=AF_INET;
hum.sin_addr.s_addr=INADDR_ANY;
hum.sin_port=htons(8888);
//Broadcast permission
if((setsockopt(s,SOL_SOCKET,SO_BROADCAST,(char *)&opt,sizeof(opt)))<0)
{
printf("\nBroadcast permissions failed ERROR CODE : %d\n",WSAGetLastError());
WSACleanup();
return 1;
}
//UDP SOCKET Binding
if((bind(s,(sockaddr *)&hum,sizeof(hum)))==SOCKET_ERROR)
{
printf("\nUDP socket binding failed ERROR CODE :%d\n",WSAGetLastError());
WSACleanup();
return 1;
}
//UDP connection thread
DWORD th;
CreateThread(NULL,0,UDPCONN,(LPVOID)s,0,&th);
CLIENT CODE :
#include "stdafx.h"
#include <stdio.h>
#include <WinSock2.h>
#pragma comment(lib,"ws2_32.lib")
int _tmain(int argc, _TCHAR* argv[])
{
//UDP Data
int slen;
char message[300];
int opt=1;
SOCKET s;
struct sockaddr_in sent;
//Initializing winsock
WSADATA wsa;
if((WSAStartup(MAKEWORD(2,2),&wsa))!=0)
{
printf("\nFailed Initializing Winsock EROR CODE : %d\n",WSAGetLastError());
return 1;
}
//UDP Socket creation
if((s=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP))== SOCKET_ERROR)
{
printf("\nUDP socket creation failed ERROR CODE :%d\n",WSAGetLastError());
WSACleanup();
return 1;
}
//UDP Broadcast permissions
if((setsockopt(s,SOL_SOCKET,SO_BROADCAST,(char *)&opt,sizeof(opt)))<0)
{
printf("\nERROR in broadcasting ERROR CODE : %d \n",WSAGetLastError());
WSACleanup();
return 1;
}
//UDP socket definition
sent.sin_family=AF_INET;
sent.sin_addr.s_addr=INADDR_ANY;
sent.sin_port=htons(8888);
//UDP Receiving broadcasted data
slen=sizeof(sent);
//fflush(stdout);
memset(message,'\0',300);
if((recvfrom(s,message,sizeof(message),0,(struct sockaddr *)&sent,&slen))<0)
{
printf("\nUDP Broadcast not received ERROR CODE : %d\n",WSAGetLastError());
WSACleanup();
return 1;
}
puts("\nGot server broadcast\n");
puts("\nTracing server ip\n");
getpeername(s,(sockaddr *)&sent,&slen);
...
}
Here my client throw an error
UDP Broadcast not received ERROR CODE : 10022
Description of the error code 10022 : Invalid argument.
Some invalid argument was supplied (for example, specifying an invalid level to the setsockopt function). In some instances, it also refers to the current state of the socket—for instance, calling accept on a socket that is not listening.
According to the error description one of the arguments in the recvfrom() function is invalid. But i could not find out the invalid argument .
Please help me clear the error.
If you read the recvfrom() documentation, it tells you exactly why you are getting the error in your client code:
Parameters
s [in]
A descriptor identifying a bound socket.
...
WSAEINVAL
The socket has not been bound with bind, or an unknown flag was specified, or MSG_OOB was specified for a socket with SO_OOBINLINE enabled, or (for byte stream-style sockets only) len was zero or negative.
You are not calling bind() on the socket before calling recvfrom(). More importantly, you cannot bind() the client and server to the same IP/port when they are running on the same machine. Change the port that you broadcast to, and then have the client bind to that port.
Also, the last two parameters of recvfrom() provide you with the IP/Port of the datagram sender. They are not for specifying the network adapter to read datagrams on. You do not need to use getpeername() in this situation.
There are some other issues with your code:
On the client side, socket() returns INVALID_SOCKET on failure, not SOCKET_ERROR.
On the server side, you really should not be using INADDR_BROADCAST. You should bind() the server socket to a specific network adapter and then sendto() its particular subnet broadcast IP, which you can calculate using GetAdaptersInfo() or GetAdaptersAddresses().
And on both sides, you cannot use WSAGetLastError() if WSAStartup() fails, that is why WSAStartup() returns the error code directly. And you are not closing the sockets before calling WSACleanup();
Try this:
SERVER CODE:
#include "stdafx.h"
#include <stdio.h>
#include <WinSock2.h>
#pragma comment (lib,"ws2_32.lib")
DWORD WINAPI UDPCONN(LPVOID x)
{
SOCKET s = (SOCKET)x;
char bro[200] = "I am SERVER";
struct sockaddr_in hum;
memset(&hum, 0, sizeof(addr));
hum.sin_family = AF_INET;
hum.sin_addr.s_addr = INADDR_BROADCAST; // TODO: replace with subnet broadcast IP
hum.sin_port = htons(8887);
while (1)
{
if (sendto(s, bro, sizeof(bro), 0, (struct sockaddr *)&hum, sizeof(hum)) == SOCKET_ERROR)
{
printf("\nBroadcast failed ERROR CODE : %d\n", WSAGetLastError());
return 1;
}
}
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
SOCKET s;
struct sockaddr_in hum;
int err, opt=1;
//Initializing winsock2
WSADATA wsa;
err = WSAStartup(MAKEWORD(2,2), &wsa);
if (err != 0)
{
printf("\nWinsock Not initialized ERROR CODE : %d\n", err);
return 1;
}
//UDP Socket Creation
s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (s == INVALID_SOCKET)
{
printf("\nUDP Socket not created ERROR CODE : %d\n", WSAGetLastError());
WSACleanup();
return 1;
}
//socket defenition
memset(&hum, 0, sizeof(hum));
hum.sin_family = AF_INET;
hum.sin_addr.s_addr = INADDR_ANY; // TODO: replace with a specific NIC IP
hum.sin_port = htons(8888);
//Broadcast permission
if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char *)&opt, sizeof(opt)) == SOCKET_ERROR)
{
printf("\nBroadcast permissions failed ERROR CODE : %d\n", WSAGetLastError());
closesocket(s);
WSACleanup();
return 1;
}
//UDP SOCKET Binding
if (bind(s, (sockaddr *)&hum, sizeof(hum)) == SOCKET_ERROR)
{
printf("\nUDP socket binding failed ERROR CODE : %d\n", WSAGetLastError());
closesocket(s);
WSACleanup();
return 1;
}
//UDP connection thread
DWORD th;
HANDLE hThread = CreateThread(NULL,0, UDPCONN, s, 0, &th);
if (!hThread)
{
printf("\nUDP thread failed ERROR CODE : %u\n", GetLastError());
closesocket(s);
WSACleanup();
return 1;
}
// do other things, wait for thread to terminate ...
DWORD exitCode = 0;
GetExitCodeThread(hThread, &exitCode);
CloseHandle(hThread);
closesocket(s);
WSACleanup();
return exitCode;
}
CLIENT CODE :
#include "stdafx.h"
#include <stdio.h>
#include <WinSock2.h>
#pragma comment(lib,"ws2_32.lib")
int _tmain(int argc, _TCHAR* argv[])
{
//UDP Data
int addrlen, msglen;
char message[300];
int err, opt=1;
SOCKET s;
struct sockaddr_in hum, addr;
//Initializing winsock
WSADATA wsa;
err = WSAStartup(MAKEWORD(2,2), &wsa);
if (err != 0)
{
printf("\nFailed Initializing Winsock EROR CODE : %d\n", err);
return 1;
}
//UDP Socket creation
s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (s == INVALID_SOCKET)
{
printf("\nUDP socket creation failed ERROR CODE : %d\n", WSAGetLastError());
closesocket(s);
WSACleanup();
return 1;
}
//UDP Broadcast permissions
if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char *)&opt, sizeof(opt)) == SOCKET_ERROR)
{
printf("\nERROR in broadcasting ERROR CODE : %d \n", WSAGetLastError());
closesocket(s);
WSACleanup();
return 1;
}
//UDP socket definition
memset(&hum, 0, sizeof(addr));
hum.sin_family = AF_INET;
hum.sin_addr.s_addr = INADDR_ANY;
hum.sin_port = htons(8887);
//UDP SOCKET Binding
if (bind(s, (sockaddr *)&hum, sizeof(hum)) == SOCKET_ERROR)
{
printf("\nUDP socket binding failed ERROR CODE : %d\n", WSAGetLastError());
closesocket(s);
WSACleanup();
return 1;
}
//UDP Receiving broadcasted data
addrlen = sizeof(addr);
msglen = recvfrom(s, message, sizeof(message), 0, (struct sockaddr *)&addr, &addrlen);
if (msglen == SOCKET_ERROR)
{
printf("\nUDP Broadcast not received ERROR CODE : %d\n", WSAGetLastError());
closesocket(s);
WSACleanup();
return 1;
}
printf("\nGot server broadcast\n");
printf("\nServer ip: %s, port: %hu\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
printf("\nMessage: %.*s\n", msglen, message);
...
}
Whatever method i tried sending a broadcast from server and receiving the broadcast from client is not working efficiently.
Instead i done the reverse i.e send a broadcast from client to search for the server is working perfectly.
Here is my modified code.
SERVER CODE:
#include "stdafx.h"
#include<stdio.h>
#include<WinSock2.h>
#pragma comment (lib,"ws2_32.lib")
DWORD WINAPI UDPCONN(LPVOID x)
{
SOCKET s=(SOCKET)x;
struct sockaddr_in server;
int len;
char buf[500]=("I am server");
char message[500];
len=sizeof(server);
int opt=1;
if((s=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP))==INVALID_SOCKET)
{
printf("\nSocket creation failed. ERROR CODE : %d\n",WSAGetLastError());
WSACleanup();
ExitThread(NULL);
}
server.sin_family=AF_INET;
server.sin_addr.s_addr=INADDR_ANY;
server.sin_port=htons(8888);
if(setsockopt(s,SOL_SOCKET,SO_BROADCAST,(char *)&opt,sizeof(opt))<0)
{
printf("\nSetting broadcast failed : %d\n",WSAGetLastError());
WSACleanup();
ExitThread(NULL);
}
if((bind(s,(sockaddr *)&server,sizeof(server)))==SOCKET_ERROR)
{
printf("\nBind failed. ERROR CODE : %d\n",WSAGetLastError());
WSACleanup();
ExitThread(NULL);
}
while(1)
{
fflush(stdout);
memset(message,'\0', 500);
//try to receive some data, this is a blocking call
if (recvfrom(s, message, 500, 0, (struct sockaddr *) &server,&len) == SOCKET_ERROR)
{
printf("recvfrom() failed with error code : %d" , WSAGetLastError());
ExitThread(NULL);
}
if(sendto(s,buf,sizeof(buf),0,(struct sockaddr *)&server,sizeof(server))==SOCKET_ERROR)
{
printf("\nIP Broadcast failed ERROR code : %d\n",WSAGetLastError());
WSACleanup();
ExitThread(NULL);
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
SOCKET s;
//struct sockaddr_in hum;
int opt=1;
//Initializing winsock2
WSADATA wsa;
if((WSAStartup(MAKEWORD(2,2),&wsa))!=0)
{
printf("\nWinsock Not initialized ERROR CODE : %d\n",WSAGetLastError());
return 1;
}
s=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
//UDP connection thread
DWORD th;
CreateThread(NULL,0,UDPCONN,(LPVOID)s,0,&th);
closesocket(s);
CLIENT CODE :
#include "stdafx.h"
#include <stdio.h>
#include <WinSock2.h>
#pragma comment(lib,"ws2_32.lib")
int _tmain(int argc, _TCHAR* argv[])
{
//UDP Data
int slen;
char message[600];
char buf[300]=("Hai server");
int opt=1;
SOCKET s;
struct sockaddr_in sent;
//TCP Connection data
SOCKET t;
struct sockaddr_in server;
char messag[300],server_reply[300];
int recv_size;
//Initializing winsock
WSADATA wsa;
if((WSAStartup(MAKEWORD(2,2),&wsa))!=0)
{
printf("\nFailed Initializing Winsock EROR CODE : %d\n",WSAGetLastError());
return 1;
}
//UDP Socket creation
if((s=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP))== INVALID_SOCKET)
{
printf("\nUDP socket creation failed ERROR CODE :%d\n",WSAGetLastError());
WSACleanup();
return 1;
}
//UDP Broadcast permissions
if((setsockopt(s,SOL_SOCKET,SO_BROADCAST,(char *)&opt,sizeof(opt)))<0)
{
printf("\nERROR in broadcasting ERROR CODE : %d \n",WSAGetLastError());
WSACleanup();
return 1;
}
//UDP socket definition
sent.sin_family=AF_INET;
sent.sin_addr.s_addr=INADDR_BROADCAST;
sent.sin_port=htons(8888);
if (sendto(s, buf, sizeof(buf) , 0 , (struct sockaddr *) &sent,sizeof(sent)) == SOCKET_ERROR)
{
printf("sendto() failed with error code : %d" , WSAGetLastError());
exit(EXIT_FAILURE);
}
//UDP Receiving broadcasted data
slen=sizeof(sent);
fflush(stdout);
memset(message,'\0',300);
if((recvfrom(s,message,sizeof(message),0,(struct sockaddr *)&sent,&slen))<0)
{
printf("\nUDP Broadcast not received ERROR CODE : %d\n",WSAGetLastError());
WSACleanup();
return 1;
}
puts("\nGot server broadcast\n");
puts("\nTracing server ip\n");
getpeername(s,(sockaddr *)&sent,&slen);
closesocket(s);
Both the codes here works perfectly fine in visual studios 2012.
Also this is just one part of my whole big program. But still this part works perfectly fine independently.
So please make sure you compiled and run the program before posting negative comments.
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 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;
}
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.