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?
Related
I am trying to implement a client-server architecture using sockets in Windows with winsock.h. When I call bind() function I get the error code 10038 and I don`t know why.
Here it is my code. This is only the server, created inside a thread where I initialice the socket and jump into an infinite loop to read data from client usng recvfrom function.
typedef struct
{
int sockfd;
struct sockaddr_in dir_client;
int long_dir_client;
struct sockaddr_in dir_server;
uint32_t receive_data;
}server_t;
void RX_thread_Client(void)
{
WSADATA wsaData;
server_t server;
int iResult;
int BytesReceived;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("[RxThreadClient] WSAStartup failed with error: %d\n", iResult);
return;
}
memset((char*)& server.dir_server, 0, sizeof(server.dir_server));
server.dir_server.sin_family = AF_INET;
server.dir_server.sin_addr.s_addr = inet_addr("10.128.169.46");
server.dir_server.sin_port = htons(6500);
server.long_dir_client = sizeof(server.dir_client);
// Create a new socket to make a client connection.
// AF_INET = 2, The Internet Protocol version 4 (IPv4) address family, TCP protocol
if ( server.sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP) == INVALID_SOCKET)
{
printf("[RxThreadClient] Client: socket() failed! Error code: %ld\n", WSAGetLastError());
// Do the clean up
WSACleanup();
// Exit with error
return;
}
else
printf("[RxThreadClient] Client: socket() is OK!\n");
if ( bind(server.sockfd, (struct sockaddr*)&server.dir_server, sizeof(server.dir_server)) < 0) // ERROR IS HERE!!!
{
printf("[RxThreadClient] bind() failed! Error code: %ld\n", WSAGetLastError());
return;
}
else
printf("[RxThreadClient] Client: bind() is OK!\n");
while (1)
{
BytesReceived = recvfrom (server.sockfd, (char*)&server.receive_data,
sizeof(server.receive_data), 0,
(struct sockaddr*) & server.dir_client,
&server.long_dir_client);
if (BytesReceived == SOCKET_ERROR)
{
printf("[RxThreadClient] Client: send() error %ld.\n", WSAGetLastError());
break;
}
else
{
printf("[RxThreadClient] Client: send() is OK - bytes received: %ld\n", BytesReceived);
printf("[RxThreadClient] Word received: %d\n", server.receive_data);
}
Sleep(1000);
}
}
Thank you very much
I 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.
Hi I'm new to socket programming. I'm currently writing c code for client, which is my computer, to send something to local host 127.0.0.1 and see if local host has got the request and anything back. I can already get connected to the local host but I don't know what command do I use to test if I can talk to the local host.
#include<stdio.h>
#include<winsock2.h>
#pragma comment(lib, "ws2_32.lib") //Winsock Library
int main(int argc, char *argv[])
{
WSADATA wsa;
SOCKET s;
struct sockaddr_in server;
char *message , server_reply[2000];
int recv_size;
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, IPPROTO_TCP)) == INVALID_SOCKET)
{
printf("Could not create socket : %d\n", WSAGetLastError());
return 1;
}
printf("Socket created.\n");
//server.sin_addr.s_addr = 127.0.0.1;
//server.sin_addr.s_addr = inet_addr("74.125.224.72"); //google IP address
server.sin_addr.s_addr = inet_addr("127.0.0.1"); //local host IP
server.sin_family = AF_INET;
//server.sin_port = htons(80);//IIS port
server.sin_port = htons(60441); //local port
//server.sin_port = 80;
//Connect to remote server
if (connect(s, (struct sockaddr *)&server, sizeof(server)) < 0)
{
printf("connect error:%d\n", WSAGetLastError());
closesocket(s);
WSACleanup();
system("pause");
return 1;
}
puts("Connected\n");
closesocket(s);
WSACleanup();
system("pause");
return 0;
}
Once you get a connection, you can use send to send a message to the remote server and recv to get a response back. Exactly what you send and what you expect to receive depend entirely on what service you're talking to.
EDIT:
As an example, suppose you're talking to a web server and you want to retrieve the main page. You could do this:
char request[] = "GET / HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n";
size_t bytesSent = send(s, request, strlen(request), 0);
if (bytesSent == -1) {
printf("Error sending: %d\n", WSAGetLastError());
return 1;
}
char response[10000];
memset(response, 0, sizeof(response));
size_t bytesRead = recv(s, response, sizeof(response), 0);
if (bytesRead == -1) {
printf("Error receiving: %d\n", WSAGetLastError());
return 1;
}
printf("response from web server: %.*s\n", bytesRead, response);
I am writing a simple client and server. I have my client written and I compared it to another server so it works perfectly. I am now trying to replicate the server, and for some reason, when my client sends a message "GET 2", the server reaches the recv function and it returns -1. Then it prints on the screen recv failed then it tries to do a shutdown but it also says shutdown failed. Does anyone know why?? I would greatly appreciate the help. Thank you!
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <WinSock2.h>
#include <WS2tcpip.h>
#pragma comment(lib, "Ws2_32.lib")
#define DEFAULT_BUFFLEN 1024
const unsigned int LISTENING_PORT = 21001;
const char ipAddress[15] = "127.0.0.1";
SOCKADDR_IN ServerAddr;
int main()
{
/*Declare and initialize variables*/
int return_Code = 10;
char recvBuff[DEFAULT_BUFFLEN] = "";
char storedQuotes[20][DEFAULT_BUFFLEN];
WSADATA wsaData;
SOCKET Socket;
SOCKET AcceptSocket;
SOCKADDR_IN ServerAddr;
/*Initialize Winsock*/
WSAStartup(MAKEWORD(2, 2), &wsaData);
/*Create New Socket*/
Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (Socket == INVALID_SOCKET)
{
printf("Server: Socket() failed! Error code: %d.\n", WSAGetLastError());
WSACleanup();
system("PAUSE");
return -1;
}
/*Specify what address to listen on*/
ServerAddr.sin_family = AF_INET; //IPv4
ServerAddr.sin_addr.s_addr = inet_addr(ipAddress); //IP Address
ServerAddr.sin_port = htons(LISTENING_PORT); //Port no.
/*Bind the Socket*/
if (bind(Socket, (SOCKADDR *)& ServerAddr, sizeof(ServerAddr)) == SOCKET_ERROR)
{
printf("Server: bind() failed! Error code: %d.\n", WSAGetLastError());
closesocket(Socket);
WSACleanup();
system("PAUSE");
return -1;
}
/*Listen on socket for a client*/
if (listen(Socket, 1) == SOCKET_ERROR)
{
printf("Sever: listen() failed! Error code: %d.\n", WSAGetLastError());
closesocket(Socket);
WSACleanup();
system("PAUSE");
return -1;
}
else
printf("Server: Listening on port %d.\n\n", LISTENING_PORT);
/*Accept a connection from a client*/
AcceptSocket = accept(Socket, NULL, NULL);
if (AcceptSocket == SOCKET_ERROR)
{
printf("Server: accept() failed! Error code: %d.\n", WSAGetLastError());
closesocket(Socket);
WSACleanup();
system("PAUSE");
return -1;
}
else
printf("Server: accept() OK!\n");
/*Receive and send data*/
//return_Code = recv(Socket, recvBuff, DEFAULT_BUFFLEN, 0);
do {
return_Code = recv(Socket, recvBuff, DEFAULT_BUFFLEN, 0);//THIS LINE RETURNS -1, SO THE MESSAGE IS NEVER PROCESSED.
//IT GOES TO RECEIVE FAILED THEN SHUTDOWN FAILED.
if (return_Code > 0)
{
if (recvBuff[0] == 'G' && recvBuff[1] == 'E' && recvBuff[2] == 'T')
{
printf("GET MESSAGE RECEIVED");
}
else if (recvBuff[0] == 'S' && recvBuff[1] == 'E' && recvBuff[2] == 'T')
{
printf("SET MESSAGE RECEIVED");
}
else
{
printf("Error: GET and SET NOT RECIEVED");
}
}
else if (return_Code == 0)
printf("Server: Connection closed!");
else
printf("Server: recv() failed! Error code: %d.\n", WSAGetLastError());
} while (return_Code > 0);
/*Disconnect*/
if (shutdown(Socket, SD_BOTH) != 0)
printf("Server: shutdown() failed! Error code: %d.\n", WSAGetLastError());
else
printf("Server: shutdown() OK!\n");
getchar();
return 0;
}
Socket is the socket that's listening for connections. AcceptSocket is the connection between your program and the client. You need to call recv with AcceptSocket, not Socket.
Also, shutdown doesn't work on listening sockets, only connected ones. The same thing applies - you can shutdown AcceptSocket but not Socket.
I am testing out a Socket Server application in c and I am getting an error on the bind function with code 10038. I looked this up and MSDN says it means:
An operation was attempted on something that is not a socket. Either the socket handle parameter did not reference a valid socket, or for select, a member of an fd_set was not valid.
Here is the code:
// I have the correct include files such as include , but stackoverflow displays it weird when i put #include winsock2.h
int main()
{
WSADATA wsaData;
SOCKET ListeningSocket;
SOCKET NewConnection;
SOCKADDR_IN ServerAddr;
int Port = 5150;
if(WSAStartup(MAKEWORD(2,2),&wsaData) != 0)
{
printf("Server: WSAStartup failed with error %ld\n",WSAGetLastError());
return -1;
}
else
{
printf("Server: The Winsock dll found!\n");
printf("Server: The current status is: %s.\n",wsaData.szSystemStatus);
}
if(LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
{
printf("Server: The dll do not support Winsock version
%u.%u!\n",LOBYTE(wsaData.wVersion),HIBYTE(wsaData.wVersion));
WSACleanup();
return -1;
}
else
{
printf("Server: The dll supports the Winsock version %u.%u!\n",LOBYTE(wsaData.wVersion),HIBYTE(wsaData.wVersion));
printf("Server: The highest version this dll can support: %u.%u\n",LOBYTE(wsaData.wHighVersion),HIBYTE(wsaData.wHighVersion));
}
ListeningSocket == socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(ListeningSocket == INVALID_SOCKET)
{
printf("Server: Error at socket(), error code: %ld\n",WSAGetLastError());
WSACleanup();
return -1;
}
else
printf("Server: socket() is OK!\n");
ServerAddr.sin_family = AF_INET;
ServerAddr.sin_port = htons(Port);
ServerAddr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(ListeningSocket, (SOCKADDR *)&ServerAddr,sizeof(ServerAddr)) == SOCKET_ERROR)
{
printf("Server: bind() failed! Error code: %ld.\n",WSAGetLastError());
closesocket(ListeningSocket);
WSACleanup();
return -1;
}
else
printf("Server: bind() is OK!\n");
if(listen(ListeningSocket,5) == SOCKET_ERROR)
{
printf("Server: listen(): Error listening on socket %ld.\n", WSAGetLastError());
closesocket(ListeningSocket);
WSACleanup();
return -1;
}
else
printf("Server: listen() is OK, I'm waiting for connections...\n");
printf("Server: accept() is ready...\n");
while(1)
{
NewConnection = SOCKET_ERROR;
while(NewConnection == SOCKET_ERROR)
{
NewConnection = accept(ListeningSocket, NULL, NULL);
}
printf("Server: accept() is OK...\n");
printf("Server: Client connected, ready for receiving and sending data...\n");
ListeningSocket = NewConnection;
break;
}
if(closesocket(NewConnection) != 0)
printf("Server: Cannot close \"NewConnection\" socket. Error code: %ld\n",
WSAGetLastError());
else
printf("Server: Closing \"NewConnection\" socket...\n");
if(WSACleanup() != 0)
printf("Server: WSACleanup() failed! Error code: %ld\n", WSAGetLastError());
else
printf("Server: WSACleanup() is OK...\n");
return 0;
}
I just got it, I put == for
ListeningSocket == socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
instea of =
ListeningSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);