I am try to write simple HTTP client with c ,
when i execute my program some time I gets data from website some time not.
to be specific recv() blocks, and the connection shutdown.
what the best way to deal with this problem ? I still want to get the website data.
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
if (iResult = getaddrinfo(s1, "http", &hints, &result)) {
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;
}
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;
}
// 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-1, 0);
if ( iResult > 0 ) {
flag = 1;
recvbuf[iResult] = '\0';
printf("%s\n",recvbuf);
}
else if ( iResult == 0 ) {
if(!flag) {
printf("conection close before recv data\n");
} else {
printf("conection close\n");
break;
}
}
else {
printf("recv failed with error: %d\n", WSAGetLastError());
}
} while(iResult>1);
// cleanup
closesocket(ConnectSocket);
WSACleanup();
return 0;
}
i've used HTTP protocol concept and sent to each url i've tried in this templet: sendbuf ="GET /[url path] HTTP 1.0/r/nHost:[www.pure_url.com]/r/n/r/n"
edit: I've tried [DaSourcerer advise] , changed to HTTP/1.1 and added Connection: close , still some time i get the data some times not.
also I added:
int tcp_timeout=10000;
unsigned int sz = sizeof(tcp_timeout);
setsockopt(ConnectSocket, SOL_SOCKET, SO_RCVTIMEO,
(char*)&tcp_timeout, sz);
this idea didn't help.
I think your timeouts are too strict. Your sent headers will also provoke servers to wait for further input. Try this:
GET /path HTTP/1.1
Host: example.com
Connection: close
It also bears mentioning that Host is a header introduced in HTTP/1.1. It has no meaning in HTTP/1.0. You may also be interested into RFC 7230, section 3.3.3 as you are almost certainly going to encounter chunk-encoded messages in HTTP/1.1. Don't worry, though: it can be parsed with a simple state machine.
Related
I would like to download a PDF file with a socket. I receive a "400 Bad Request" error from the server, saying "The plain HTTP request was sent to HTTPS port", like shown in the image below (I open it as an HTML page):
I change the port from 443 to 80, but I don't get a response from the server. I have nothing in file.pdf when I change the port to 80.
This is my console output:
Connected to server via socket 268
Bytes Sent: 109
Bytes received: 0
Received byte = 100
Total data = 100Bytes received: 0
Received byte = 100
Total data = 200Bytes received: 0
Received byte = 100
Total data = 300Bytes received: 0
Received byte = 100
Total data = 400Bytes received: 0
Received byte = 30
Total data = 430Connection closed
Received byte = 0
Total data = 430Reply received
This is my code. I open the socket and I connect to the server, but I'm not receiving the file:
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;
}
sockaddr_in Serv_Addr;
//intialisation
struct addrinfo* result = NULL;
struct addrinfo hints;
ZeroMemory(&hints, sizeof(hints));
//socket configuration
SOCKET TcpClientSocket = -1;
int ret = 0;
TcpClientSocket = socket(AF_INET, SOCK_STREAM, 0);
if (TcpClientSocket == INVALID_SOCKET) {
wprintf(L"socket function failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
Serv_Addr.sin_family = AF_INET;
Serv_Addr.sin_port = htons(443);
Serv_Addr.sin_addr.s_addr = inet_pton(AF_INET, "47.88.2.145", &Serv_Addr.sin_addr); //connect to www.axmag.com, link pdf file http://www.axmag.com/download/pdfurl-guide.pdf
printf("Connected to server via socket %u\n", TcpClientSocket);
//connection
iResult = -1;
iResult = connect(TcpClientSocket, (sockaddr*)& Serv_Addr, sizeof(Serv_Addr));
printf("%d", iResult);
if (iResult == SOCKET_ERROR) {
wprintf(L"connect function failed with error: %ld\n", WSAGetLastError());
iResult = closesocket(TcpClientSocket);
if (iResult == SOCKET_ERROR)
wprintf(L"closesocket function failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
// send request
const char* message;
message = "GET /download/pdfurl-guide.pdf HTTP/1.1\r\nHost: www.axmag.com\r\n\r\n Connection: keep-alive\r\n\r\n Keep-Alive: 300\r\n";
// test send succeded
iResult = send(TcpClientSocket, message, strlen(message), 0);
if (iResult == SOCKET_ERROR)
{
printf("send failed: %d\n", WSAGetLastError());
closesocket(TcpClientSocket);
WSACleanup();
return 1;
}
printf("Bytes Sent: %ld\n", iResult);
// shutdown the connection for sending since no more data will be sent
// the client can still use the ConnectSocket for receiving data
iResult = shutdown(TcpClientSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed: %d\n", WSAGetLastError());
closesocket(TcpClientSocket);
WSACleanup();
return 1;
}
FILE* stream;
fopen_s(&stream, "1.html", "w+");
/////receive response from server
int totalData = 0, received_data = 0;
do
{
char server_reply[100];
received_data = recv(TcpClientSocket, server_reply, sizeof server_reply, 0);
if (received_data > 0)
printf("Bytes received: %d\n", iResult);
else if (received_data == 0)
printf("Connection closed\n");
else
printf("recv failed: %d\n", WSAGetLastError());
totalData += received_data;
fwrite(server_reply, received_data, 1, stream);
printf("\nReceived byte = %d\nTotal data = %d", received_data, totalData);
} while (received_data > 0);
printf("Reply received\n");
if (stream)
{
if (fclose(stream))
{
printf("The file 'crt_fopen.c' was not closed\n");
}
}
You need a TLS library so you can speek https to the server.
This is far too big to post an answer in C but since you are using Winsock you might as well use the builtin schannel.
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();
}
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;
}
I'm a novice/beginner programmer having problems getting some simple client/server C code working. My end goal is to send a 'stream' of azimuth/elevation data from a server to a client, and then convert that data as it is received (it will just be a division, but I don't really know how to do this either) into position data for a pan/tilt unit, and then output the converted data via serial to the pan/tilt head. (I'll likely be back to ask about that later...)
Right now I'm just trying to figure out how to get the data sent and received. I grabbed code from this website. http://www.tenouk.com/Winsock/Winsock2example3.html. I had to move a few declarations around to get the code to compile.
I'm using Windows 7 and VS2010 professional on the client pc. There is no router in between the client and server (they're directly connected via ethernet).
Using the debugger, I found that I'm getting hung up at this point.
clientService.sin_family = AF_INET;
clientService.sin_addr.s_addr = inet_addr("12.266.66.255");
clientService.sin_port = htons(55555);
if (connect(m_socket, (SOCKADDR*)&clientService, sizeof(clientService)) == SOCKET_ERROR)
{
printf("Client: connect() - Failed to connect.\n");
WSACleanup();
return 0;
}
else
{
printf("Client: connect() is OK.\n");
printf("Client: Can start sending and receiving data...\n");
}
I always get the "failed to connect" message, and I'm not sure why. I am using the correct IP address of the host computer (I changed it before putting on here).
If this is a bad example to use, I'm open to starting over with another example. I've tried several of the 'echo' examples commonly found online, and I'm getting similar problems. I can give more info on my overall program goals as well if that would help. The rest of the client code is below. I'm using the server code (with declarations moved around) from the same link. Thanks.
int main()
{
int m_socket;
struct sockaddr_in clientService;
int bytesSent;
int bytesRecv = SOCKET_ERROR;
// Be careful with the array bound, provide some checking mechanism...
char sendbuf[200] = "This is a test string from client";
char recvbuf[200] = "";
// Initialize Winsock.
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != NO_ERROR)
printf("Client: Error at WSAStartup().\n");
else
printf("Client: WSAStartup() is OK.\n");
// Create a socket
m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (m_socket == INVALID_SOCKET)
{
printf("Client: socket() - Error at socket(): %ld\n", WSAGetLastError());
WSACleanup();
return 0;
}
else
printf("Client: socket() is OK.\n");
// Connect to a server.
// Just test using the localhost, you can try other IP address
clientService.sin_family = AF_INET;
clientService.sin_addr.s_addr = inet_addr("12.233.21.254");
clientService.sin_port = htons(55555);
if (connect(m_socket, (SOCKADDR*)&clientService, sizeof(clientService)) == SOCKET_ERROR)
{
printf("Client: connect() - Failed to connect.\n");
WSACleanup();
return 0;
}
else
{
printf("Client: connect() is OK.\n");
printf("Client: Can start sending and receiving data...\n");
}
// Send and receive data.
// Receives some test string to server...
while(bytesRecv == SOCKET_ERROR)
{
bytesRecv = recv(m_socket, recvbuf, 200, 0);
if (bytesRecv == 0 || bytesRecv == WSAECONNRESET)
{
printf("Client: Connection Closed.\n");
break;
}
if (bytesRecv < 0)
return 0;
else
{
printf("Client: recv() is OK.\n");
printf("Client: Received data is: \"%s\"\n", recvbuf);
printf("Client: Bytes received is: %ld.\n", bytesRecv);
}
}
// Sends some test data to server...
bytesSent = send(m_socket, sendbuf, strlen(sendbuf), 0);
if(bytesSent == SOCKET_ERROR)
printf("Client: send() error %ld.\n", WSAGetLastError());
else
{
printf("Client: send() is OK - Bytes sent: %ld\n", bytesSent);
printf("Client: The test string sent: \"%s\"\n", sendbuf);
}
WSACleanup();
return 0;
}
Your original code (after I changed the IP and port, obviously) connected to my web-server just fine, but I did tweak it a bit (below).
While it might be a bit much, CSocketServer contains a wealth of good ol' WinSock code that's been tried and held true.
Anyway, this code connected to my local web server, sent a rudimentary request and received a response.
int WSATest()
{
// Initialize Winsock.
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR)
{
printf("Client: Error at WSAStartup().\n");
return 0;
}
// Create a socket
SOCKET m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (m_socket == INVALID_SOCKET)
{
printf("Client: socket() - Error at socket(): %ld\n", WSAGetLastError());
WSACleanup();
return 0;
}
else {
printf("Client: socket() is OK.\n");
}
struct sockaddr_in clientService;
clientService.sin_family = AF_INET;
clientService.sin_addr.s_addr = inet_addr("127.0.0.1");
clientService.sin_port = htons(9990);
//Connect to the remote peer:
if (connect(m_socket, (SOCKADDR*)&clientService, sizeof(clientService)) == SOCKET_ERROR)
{
printf("Client: connect() - Failed to connect.\n");
WSACleanup();
return 0;
}
else
{
printf("Client: connect() is OK.\n");
printf("Client: Can start sending and receiving data...\n");
}
//Very, very basic HTTP request.
int iSendResult = send(m_socket, "GET / \n\n", 8, 0);
if(iSendResult == SOCKET_ERROR)
{
printf("Failed to send data, error %d.\n", WSAGetLastError());
return 0;
}
while(true)
{
char sRecvBuffer[200];
int iRecvResult = recv(m_socket, sRecvBuffer, sizeof(sRecvBuffer) - 1, 0);
if(iRecvResult <= SOCKET_ERROR)
{
printf("Failed to receive data, error %d.\n", WSAGetLastError());
break;
}
else if(iRecvResult == 0)
{
//Graceful disconnect.
break;
}
else {
//Be sure to terminate the buffer.
sRecvBuffer[iRecvResult] = '\0';
}
printf("Received: [%s] for [%d] bytes.\n", sRecvBuffer, iRecvResult);
}
WSACleanup();
return 0;
}
int main()
{
WSATest();
system("Pause");
}
Why not add a WSAGetLastError() to check the actual error?
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.