Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Windows Socket Programming in C

I am taking a networking class where the Professor is literally reading the book to the class. Needless to say I have no Idea what I am doing. Our semester project is to copy code from our text book and make a client-server network. Literally copying the code from teh book with no modifications.

The book had mistakes in the code (missing semicolons, extra paranthesis) but I managed to at least compile the code. However, I run into a bunch of link errors.

Example: Error 1 error LNK2019: unresolved external symbol impsendto@24 referenced in function _main C:\Users\Documents\Visual Studio 2010\Projects\Client_Server\Client_Server\Client_Server\Server.obj Client_Server

i looked up the error code and I think the code is trying to link to definitions that are not existent in the header files. I have a tough time fixing LNK errors vs Syntax errors. But like I said I have no idea how to go about fixing this. I am sending the code for the server side, I ran into the same errors on the client side.

include <stdio.h>
include <string.h>
include <WinSock2.h>
include <WinSock.h>
include <stdint.h>
include <time.h>

int main(void) {

int s;      
int len;
char  buffer[256];  
struct sockaddr_in servAddr; 
struct sockaddr_in clntAddr; 

int clntAddrLen; //length of client socket addre

//Build local (server) socket add

memset(&servAddr, 0, sizeof(servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons(21);
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);

   //create socket
if((s=socket(PF_INET, SOCK_DGRAM, 0) <0 ))
{
   perror("Error: Socket Failed!");
    exit(1);
}

//bind socket to local address and port
if((bind(s,(struct sockaddr*)&servAddr, sizeof(servAddr))<0))
{
    perror("Error:bind failed!");
    exit(1);
}

for(;;)
{
len = recvfrom(s,buffer, sizeof(buffer),0,(struct sockaddr*)&clntAddr, &clntAddrLen);

    //send string
    sendto(s, buffer, len, 0, (struct sockaddr*)&clntAddr, sizeof(clntAddr));
}

}

Any tips, links to useful info, or advice would be appreciated. I tried reading the text book but I am completely lost. Also, this is the only code related assignment we have done all semester. Everything else has been collecting packets using a packet sniffer. Literally came into class and said copy and run code on page X.

like image 862
networkingNoob Avatar asked Jul 21 '11 00:07

networkingNoob


3 Answers

You need to link the library Ws2_32.lib to use winsock. You also must call WSAStartup before using any other winsock functions (this isn't causing your current error, but will cause you problems once you fix the missing library issue).

like image 71
bdonlan Avatar answered Sep 22 '22 04:09

bdonlan


At first I will try to help using your last comment: Let us assume you are using Visual Studio (I think it is best option to start winsock for windows programming as Microsoft cares about Windows basic libraries being up to date and they are compatible with helpful msdn support).

If you are getting error such as this one: 1>asdf.obj : error LNK2001: unresolved external symbol _imp_WSAStartup@8 it means that ws2_32.lib is not linked correctly. To do that right click on your project in solution explorer, go to linker -> input and add ws2_32.lib to additional dependencies. This library is part of windows SDK (I guess it is installed together with most versions of Visual Studio), so make sure the file exists on your computer.

And now how to make correct project in modern style without following ancient tutorials:

The library you need to add is Winsock2.h. Winsock.h is old (deprecated) version and there is no need to use it in new applications. To start using sockets you need to call function WSAStartup, to do that you must initialize struct WSADATA at the beginning. The basic piece of code looks like this:

#include <Winsock2.h>
int main()
{
WSADATA mywsadata; //your wsadata struct, it will be filled by WSAStartup
WSAStartup(0x0202,&mywsadata); //0x0202 refers to version of sockets we want to use.
//here goes your code with socket related things
return 0;
}

For more help you can visit here

A note: since question is old and I am not sure its author will ever find my answer helpful I want to help another users looking at this question

like image 22
2 revs, 2 users 94% Avatar answered Sep 26 '22 04:09

2 revs, 2 users 94%


The following is a simple socket program (simple http client) that will run on both Windows and Linux. If you are using "gcc on windows" then you need to compile using the following command:

gcc prog_name.c -lws2_32

Code:

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#if defined(_WIN32) || defined(_WIN64)
    #include <winsock2.h>
#else
    #include <sys/socket.h>
    #include <arpa/inet.h>
#endif

#define MSG_SIZE 1024
#define REPLY_SIZE 65536

int main(int argc, char *argv[])
{
    int s = -1;
    struct sockaddr_in server;
    char message[MSG_SIZE] = {0}, server_reply[REPLY_SIZE] = {0};
    int recv_size = 0;

#if defined(_WIN32) || defined(_WIN64)    
    WSADATA wsa;
    if (WSAStartup(MAKEWORD(2,2),&wsa) != 0) {
        printf("\nError: Windows socket subsytsem could not be initialized. Error Code: %d. Exiting..\n", WSAGetLastError());
        exit(1);
    }
#endif
    
    //Create a socket
    if((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)    {
        printf("Error: Could not create socket: %s. Exiting..\n", strerror(errno));
        exit(1);
    }

    // Fill in server's address
    memset(&server, 0, sizeof(server));
    server.sin_addr.s_addr = inet_addr("172.217.160.238"); // google.com
    server.sin_family = AF_INET;
    server.sin_port = htons(80);

    // Connect to server
    if (connect(s, (struct sockaddr *)(&server), sizeof(server)) < 0) {
        printf("Error: Could not connect to server: %s. Exiting..\n", strerror(errno));
        exit(1);
    }
    
    // Send HTTP request
    strcpy(message, "GET / HTTP/1.1\r\n\r\n");
    if(send(s, message, strlen(message), 0) < 0) {
        printf("Error: Could not send http request to server: %s. Exiting..\n", strerror(errno));
        exit(1);
    }
    
    // Receive a reply from the server
    printf("\nWaiting for server reply..\n");
    if((recv_size = recv(s, server_reply, REPLY_SIZE, 0)) < 0) {
        printf("Error: Something wrong happened while getting reply from server: %s. Exiting..\n", strerror(errno));
        exit(1);
    }

    server_reply[REPLY_SIZE - 1] = 0;

    printf("\nServer Reply:\n\n");
    printf("%s\n", server_reply);

    // Close the socket
#if defined(_WIN32) || defined(_WIN64)  
    closesocket(s);
    WSACleanup();
#else
    close(s);
#endif

    exit(0);
} // end of main
like image 30
Amit Avatar answered Sep 23 '22 04:09

Amit