recv() - Working with HTTP headers - c

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.

Related

How to send something to the server?

I was given this code and my task is to send something to the server using the console and read it in it.
Maybe someone knows how to do it for me or maybe give me a hint where to start.
Because we were given the source code but how to work with it and what to do next, we were not told anything
Maybe someone already has experience in this and can help
#include <stdio.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <conio.h>
#include <string.h>
#pragma comment (lib, "Ws2_32.lib")
int main() {
WSADATA wsaData;
int iResult;
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed: %d\n", iResult);
return 1;
}
struct addrinfo *result = NULL, *ptr = NULL;
struct addrinfo hints;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
iResult = getaddrinfo("147.175.115.34", "777", &hints, &result);
if (iResult != 0) {
printf("getaddrinfo failed: %d\n", iResult);
WSACleanup();
return 1;
} else
printf("getaddrinfo did not fail...\n");
SOCKET ConnectSocket = INVALID_SOCKET;
ptr = result;
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
printf("Error at socket(): %d\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return 1;
} else
printf("Any error occured...\n");
iResult = connect(ConnectSocket, ptr->ai_addr, (int) ptr->ai_addrlen);
if (iResult == SOCKET_ERROR)
printf("Not connected to server...\n");
else
printf("Connected to server!\n");
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
WSACleanup();
return 1;
}
Sleep(250);
char sendbuf[4096];
iResult = send(ConnectSocket, sendbuf, (int)strlen(sendbuf), 0);
if (iResult == SOCKET_ERROR)
{
printf("send failed: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
printf("Bytes Sent: %d\n", iResult);
#define DEFAULT_BUFLEN 4096
int recvbuflen = DEFAULT_BUFLEN;
char recvbuf[DEFAULT_BUFLEN];
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());
closesocket(ConnectSocket);
WSACleanup();
}
well you need to put something in 'sendbuf' before the send call.
like say
strcpy(sndbuf, "Hello Server");
BTW the receive code is totally wrong. You must loop on the receive until you have received all the data

winsock client repeatedly try to connect to server

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.

Winsock recv() blocks but exits after an interval

This question has been asked before here
Winsock recv() does not block and
here C++ Winsock recv not blocking and I have gone through the solutions but of no avail.
My scenario is as follows:
I have setup a LWIP server in VC707 FPGA kit and windows client on my PC. Client sends some data to the server and then goes into an infinite while loop where it waits to recv() data from the server.
The server on the other hand, receives data from the client, calls a data processing operation and then sends back the data.
The issue I am facing here is that after the server receives the data, it takes about 1 minute for the process to be complete and post that it will send the data. However, the recv() function on the client side, waits for the data for about 30-35s (clocked by watch) and then returns -1 and socket error 10057 and in earlier case 10060, which means that the connection has been terminated.
Please let me know where and what I am doing wrong.
client.c:
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <conio.h>
#pragma comment(lib,"ws2_32.lib")
#define DEFAULT_PORT "9881"
#define DEFAULT_BUFLEN 1460
//#define DEFAULT_BUFLEN 2048
#define DEFAULT_RECV_LEN 2048
#define server_addr "192.168.1.10"
FILE *fid, *fdr;
int main(int argc, char *argv[]) {
int iResult, recvbuflen = DEFAULT_RECV_LEN, file_pos = 0;
int bytesRead=0, i=0;
unsigned char sendbuf[DEFAULT_BUFLEN]={NULL}, recvbuf[DEFAULT_RECV_LEN]={NULL};
char filename[256];
WSADATA wsaData;
struct addrinfo *result = NULL,*ptr = NULL,hints;
SOCKET ConnectSocket = INVALID_SOCKET;
int j, iter=0;
unsigned total_bytes_rx = 0,data_tx_cnt = 0,data_tx_pack_cnt=0;
unsigned uiNoBytes2Send = 1024;
unsigned uiNoPackets2Send = 10;
printf("enter file to transfer: \n");
scanf("%s", filename);
printf("Enter number of packets to send (packet size : 1460):");
scanf("%u",&uiNoPackets2Send);
fid=fopen(filename,"rb");
fdr=fopen("D:\\Saravana\\UMA\\DataFiles\\recvfile.bin","wb");
//fclose(fdr);
//fdr=fopen("recvfile.txt","w");
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed: %d\n", iResult);
getch();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(server_addr, DEFAULT_PORT, &hints, &result);
if (iResult != 0) {
printf("getaddrinfo failed: %d\n", iResult);
WSACleanup();
getch();return 1;
}
ptr=result;
// Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
printf("Error at socket(): %ld\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
getch();return 1;
}
// Connect to server.
iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
}
freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET) {
printf("Unable to connect to server!\n");
WSACleanup();
getch();return 1;
}
//bytesRead=fread(&sendbuf[4],1,DEFAULT_BUFLEN,fid);
printf("****** Data Sending Initiated ******\n");
printf("\n **** Sending control packet ****");
sendbuf[0]='c'; sendbuf[1]='t'; sendbuf[2]='r'; sendbuf[3]='l'; //Control string
sendbuf[4] = 0xC2; sendbuf[5] = 0x00; sendbuf[6] = 0x00; sendbuf[7] = 0x00; //SDRAM Address
//#Bytes to transfer
sendbuf[8] = (uiNoPackets2Send&0xFF000000)>>24;
sendbuf[9] = (uiNoPackets2Send&0x00FF0000)>>16;
sendbuf[10] = (uiNoPackets2Send&0x0000FF00)>>8;
sendbuf[11] = (uiNoPackets2Send&0x000000FF);
printf("\n Send buf[11] : %u",sendbuf[11]);
//iResult = send(ConnectSocket, sendbuf, bytesRead+4, 0);
iResult = send(ConnectSocket, sendbuf, DEFAULT_BUFLEN, 0);
if (iResult == SOCKET_ERROR) {
printf("send failed: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
getch();return 1;
}
else
{
printf("\n Control packet sent successfully");
}
printf("\n Starting Data packet transfer ..");
printf("\n");
while(data_tx_pack_cnt<uiNoPackets2Send)
{
bytesRead=fread(&sendbuf[0],1,DEFAULT_BUFLEN,fid);
if(bytesRead<DEFAULT_BUFLEN)
break;
//iResult = send(ConnectSocket, sendbuf, bytesRead+4, 0);
iResult = send(ConnectSocket, sendbuf, DEFAULT_BUFLEN, 0);
if (iResult == SOCKET_ERROR) {
printf("send failed: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
getch();return 1;
}
data_tx_cnt += iResult;
data_tx_pack_cnt++;
printf("\r Current Bytes sent : %u \t Current packet cnt : %u ",iResult,data_tx_pack_cnt);
}
printf("\n Total bytes transferred: %u\n",data_tx_cnt);
strcpy(sendbuf,"term");
iResult = send(ConnectSocket, sendbuf, 1460, 0) ;
if(iResult <0)
{
puts("Send failed\n");
return 1;
}else
printf("\n Control Packet sent to indicate data transfer is complete\n");
if (iResult == SOCKET_ERROR) {
printf("shutdown failed: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
getch();return 1;
}*/
printf("****** Switching to data receive mode ******\n");
//Receive until the server closes the connection
while(1) {
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
printf("iResult: %d\n",iResult);
if ( iResult > 0 )
{
if ( recvbuf[iResult-5]=='m' && recvbuf[iResult-4]=='s' && recvbuf[iResult-3]=='d' &&
recvbuf[iResult-2]=='p' && recvbuf[iResult-1]=='d')
{
//fwrite(recvbuf,sizeof(char),iResult-5,fdr);
printf("Connection terminated\n");
break;
}
fwrite(recvbuf,sizeof(char),iResult,fdr);
//if(total_bytes_rx%(1024*1024)== 0)
total_bytes_rx +=iResult;
printf("\rBytes received: Global %u \t Local : %u", total_bytes_rx,iResult);
//printf("Bytes received: Local : %u\n",iResult);
//fclose(fdr);
}else{
printf("recv failed: %d\n Closing all Open Sockets\n", WSAGetLastError());
break;
}
} //while( iResult > 0 );
end_pgm:
fclose(fid);
fclose(fdr);
closesocket(ConnectSocket);
WSACleanup();
printf("Total Bytes received: %d\n", total_bytes_rx);
getch();
}

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.

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;
}

Resources