Winsock send () over TCP in C - c

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:)

Related

Winsock client and server wont connect

I have written a client and server using winsock2. The server seems to run fine but when I run the client it returns the 10038 error code for "Socket operation on nonsocket" immediately. Not sure why its doing that at is will create the socket with returning an error.
Here is the code for the client, It fails on the connect function call:
#include <stdio.h>
#include <winsock2.h>
#include <time.h>
#pragma comment(lib,"ws2_32.lib") //Winsock Library
int main(int *argc, char **argv){
struct sockaddr_in server, client;
char server_reply[2000];
WSADATA wsa;
int result = WSAStartup(MAKEWORD(2,2),&wsa);
SOCKET sock, newSock;
if ((sock = socket(AF_INET, SOCK_STREAM, 0) == INVALID_SOCKET)){
printf("Failed to create socketwith error code : %d" , WSAGetLastError());
}
else{
printf("Socket created\n");
}
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons(8080);
if((newSock = connect(sock , (struct sockaddr *)&server , sizeof(server)) == INVALID_SOCKET )){
printf("connect failed with error code : %d" , WSAGetLastError());
}
else{
printf("connected");
}
closesocket(socket);
WSACleanup();
return 0;
}
The code for the server which I believe works:
#include<io.h>
#include<stdio.h>
#include<winsock2.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;
char message[54];
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( 8080 );
//Bind
if( bind(s ,(struct sockaddr *)&server , sizeof(server)) == SOCKET_ERROR)
{
printf("Bind failed with error code : %d" , WSAGetLastError());
return 1;
}
puts("Bind done");
//Listen to incoming connections
listen(s , 3);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
while( (new_socket = accept(s , (struct sockaddr *)&client, &c)) != INVALID_SOCKET )
{
recv(s, message, 2000, 0);
printf(message);
}
if (new_socket == INVALID_SOCKET)
{
printf("accept failed with error code : %d" , WSAGetLastError());
return 1;
}
closesocket(s);
WSACleanup();
return 0;
}
You are setting the parentheses wrong:
if ((sock = socket(AF_INET, SOCK_STREAM, 0) == INVALID_SOCKET))
assigns 0 to "sock", you want the following:
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
to have the comparison after the assignment, instead of assigning the result of the comparison. This is a matter of operator precedence, == "winning" over =.

Getting wrong ip address and port number from recvfrom

I get the following ip and port "204.204.204.204#52428" no matter what my ip and port are. I am using windows 10 and ipv4 address
#include "stdafx.h"
#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(int argc, char **argv)
{
WSADATA wsaData;
int iResult;
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
struct addrinfo *result = NULL;
struct addrinfo hints;
int iSendResult;
char recvbuf[DEFAULT_BUFLEN];
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;
}
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, argv[1], &hints, &result);
if (iResult != 0) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// 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;
}
// 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;
}
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);
struct sockaddr_in from_addr;
socklen_t fromlen = sizeof(from_addr);
char from_ip[2048] = "";
int nbytes = 0;
// Receive until the peer shuts down the connection
do {
nbytes = recvfrom(ClientSocket, recvbuf, recvbuflen, 0, (sockaddr *) &from_addr, &fromlen);
InetNtop(AF_INET, &from_addr.sin_addr, from_ip, sizeof(from_ip));
if (nbytes > 0) {
printf("Received %d bytes from %s#%d", nbytes, from_ip, ntohs(from_addr.sin_port));
// Echo the buffer back to the sender
iSendResult = send(ClientSocket, recvbuf, nbytes, 0);
if (iSendResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
printf("\tBytes sent: %d\n", iSendResult);
}
else if (nbytes == 0)
printf("Connection closing...\n");
else {
printf("recv failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
fromlen = sizeof(from_addr);
} while (nbytes > 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();
return 0;
}
where printing happens in this block
struct sockaddr_in from_addr;
socklen_t fromlen = sizeof(from_addr);
char from_ip[2048] = "";
int nbytes = 0;
// Receive until the peer shuts down the connection
do {
nbytes = recvfrom(ClientSocket, recvbuf, recvbuflen, 0, (sockaddr *) &from_addr, &fromlen);
InetNtop(AF_INET, &from_addr.sin_addr, from_ip, sizeof(from_ip));
if (nbytes > 0) {
printf("Received %d bytes from %s#%d", nbytes, from_ip, ntohs(from_addr.sin_port));
// Echo the buffer back to the sender
iSendResult = send(ClientSocket, recvbuf, nbytes, 0);
if (iSendResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
printf("\tBytes sent: %d\n", iSendResult);
}
else if (nbytes == 0)
printf("Connection closing...\n");
else {
printf("recv failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
fromlen = sizeof(from_addr);
} while (nbytes > 0);
I am not sure how to resolve this problem?
Don't call recvfrom() on a TCP socket. I'm surprised it works at all; I suppose it "reverts" to recv() behavior and ignores the source address & length parameters.
You can get the peer's address info from the accept() call.

Other PC can't connect to my server in C

I made a Server in C on port 100. The problem is that if anyone out of my PC writes telnet myip 100 he can't connect to my server!
Code:
#include <io.h>
#include <stdio.h>
#include <winsock2.h>
#include <Ws2tcpip.h>
#include "ws2tcpip.h"
#pragma comment(lib,"ws2_32.lib")
int main(int argc , char *argv[])
{
WSADATA wsa;
SOCKET s, new_socket;
struct sockaddr_in server, client;
int c;
char *message;
printf("\nInitialising Winsock...\n");
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
{
printf("Failed. Error Code : %d",WSAGetLastError());
return 1;
}
printf("Winsock 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(100);
int inet_pton(int af, const char *src, void *dst);
//Bind
if( bind(s ,(struct sockaddr *)&server , sizeof(server)) == SOCKET_ERROR)
{
printf("Bind failed with error code: %d" , WSAGetLastError());
exit(EXIT_FAILURE);
}
puts("Bind done");
//Listen to incoming connections
listen(s, 3);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
while( (new_socket = accept(s , (struct sockaddr *)&client, &c)) != INVALID_SOCKET )
{
puts("Connection accepted");
//Reply to the client
message = "Hello Client, I have received your connection. But I have to go now... bye!\n";
send(new_socket, message, strlen(message) , 0);
}
if (new_socket == INVALID_SOCKET)
{
printf("Accept failed with error code: %d" , WSAGetLastError());
return 1;
}
closesocket(s);
WSACleanup();
return 0;
}
My provider is Fastweb (i'm from italy, i don't know if you know it).
What's the problem? The source code of the server or the provider?
Thank you a lot!

I can't set up a server on windows 7 to listen on to a specific port

I want to learn some network programming in C with winapi.
That's the code. The problem. It runs only on port 5555, not the one I specified. It compiles and runs. The windows firewall pops up and I authorize the application. I scanned my computer with nmap using connect() parameter and it closes the connection making me sure this application is running on port 5555. Yet, it doesn't display anything on the screen, except for when the connection is terminated.
The commented part is the other way I tried to setup the server. I tried two approaches and both didn't work perfectly. Thanks in advance.
#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, "Mswsock.lib")
#define DEFAULT_BUFLEN 1024
int __cdecl main(void)
{
WSADATA wsaData;
int iResult;
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
struct addrinfo *result = NULL;
struct addrinfo hints;
int iSendResult;
char recvbuf[DEFAULT_BUFLEN];
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;
}
struct sockaddr_in my_addr, *p;
//ZeroMemory(&hints, sizeof(hints));
my_addr.sin_family = AF_INET;
my_addr.sin_addr.s_addr = inet_addr(192.168.0.102)
my_addr.sin_port = htons(9998);
memset(my_addr.sin_zero,'\0', sizeof(my_addr.sin_zero));
/*
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("192.168.0.102", "3222", &hints, &result);
if ( iResult != 0 ) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}*/
//Create a SOCKET for connecting to server
ListenSocket = socket(p->sin_family, p->sin_socktype, p->sin_protocol);
//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;
}
// Setup the TCP listening socket
iResult = bind( ListenSocket, 192.168.0.102, (int)p->sin_addrlen);
if (iResult == SOCKET_ERROR) {
printf("bind failed with error: %d\n", WSAGetLastError());
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
return 1;
}
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 {
printf("Running on port: %d\n", p->sin_port)
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, recvbuf, iResult, 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();
return 0;
}
There are a bunch of errors in your code.
Try this:
#undef UNICODE
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <stdlib.h>
#include <stdio.h>
// Need to link with Ws2_32.lib
// #pragma comment (lib, "Mswsock.lib")
#define DEFAULT_BUFLEN 1024
int __cdecl main(void)
{
WSADATA wsaData;
int iResult;
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
int iSendResult;
char recvbuf[DEFAULT_BUFLEN];
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0)
{
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
struct sockaddr_in my_addr;
short my_port = 9998;
memset(&my_addr, 0, sizeof(my_addr));
my_addr.sin_family = AF_INET;
my_addr.sin_addr.s_addr = inet_addr("192.168.0.102");
my_addr.sin_port = htons(my_port);
// Resolve the server address and port
//Create a SOCKET for connecting to server
ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ListenSocket == INVALID_SOCKET)
{
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
// Setup the TCP listening socket
iResult = bind(ListenSocket, (struct sockaddr*)&my_addr, sizeof(my_addr));
if (iResult == SOCKET_ERROR)
{
printf("bind failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
iResult = listen(ListenSocket, SOMAXCONN);
if (iResult == SOCKET_ERROR)
{
printf("listen failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
printf("Listening on port: %hd\n", my_port);
// 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);
printf("Client connected\n");
// Receive until the peer shuts down the connection
do
{
iResult = recv(ClientSocket, recvbuf, sizeof(recvbuf), 0);
if (iResult > 0)
{
printf("Bytes received: %d\n", iResult);
// Echo the buffer back to the sender
iSendResult = send( ClientSocket, recvbuf, iResult, 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");
break;
}
else
{
printf("recv failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
}
while (true);
// 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();
return 0;
}
Or this:
#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, "Mswsock.lib")
#define DEFAULT_BUFLEN 1024
int __cdecl main(void)
{
WSADATA wsaData;
int iResult;
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
struct addrinfo *result = NULL;
struct addrinfo hints;
int iSendResult;
char recvbuf[DEFAULT_BUFLEN];
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0)
{
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
short my_port = 9998;
char my_port_str[6];
sprintf(my_port_str, "%hu", my_port);
memset(&hints, 0, 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("192.168.0.102", my_port_str, &hints, &result);
if (iResult != 0)
{
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
//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;
}
// Setup the TCP listening socket
iResult = bind(ListenSocket, result->ai_addr, result->ai_addrlen);
if (iResult == SOCKET_ERROR)
{
printf("bind failed with error: %d\n", WSAGetLastError());
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
return 1;
}
freeaddrinfo(result);
iResult = listen(ListenSocket, SOMAXCONN);
if (iResult == SOCKET_ERROR)
{
printf("listen failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
printf("Listening on port: %hd\n", my_port);
// 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);
printf("Client connected\n");
// Receive until the peer shuts down the connection
do
{
iResult = recv(ClientSocket, recvbuf, sizeof(recvbuf), 0);
if (iResult > 0)
{
printf("Bytes received: %d\n", iResult);
// Echo the buffer back to the sender
iSendResult = send(ClientSocket, recvbuf, iResult, 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");
break;
}
else
{
printf("recv failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
}
while (true);
// 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();
return 0;
}

recv() - Working with HTTP headers

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.

Resources