Search code examples
capigoogle-translate

Receiving data through winsockets in C


I am trying to make a translator in C using Google's translator API.

So far i've been able to create sockets, initialize them and connect them. I've sent the url that is supposed to be translating the text, but the reply size is zero bytes. The objective is to perhaps receive it as a text file or just a string.

This is the code so far.

#include<stdio.h>
#include<winsock2.h>
#include "count.c"

#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 , 0 )) == INVALID_SOCKET)
    {
        printf("Could not create socket : %d" , WSAGetLastError());
    }

    printf("Socket created.\n");

    system("ping translate.googleapis.com");

    const char* ipadress;
    printf("Enter IP adress of Hostname\n");

    scanf("%s",ipadress);

    server.sin_addr.s_addr = inet_addr(ipadress);
    server.sin_family = AF_INET;
    server.sin_port = htons( 80 );

    // Connect to remote server
    if (connect(s , (struct sockaddr *)&server , sizeof(server)) < 0)
    {
        puts("connect error");
        return 1;
    }

    puts("Connected");

    // Send some data
    message = "https://translate.googleapis.com/translate_a/single?client=gtx&sl=en&tl=da&dt=t&q=Hello";
    if( send(s , message , strlen(message) , 0) < 0)
    {
        puts("Send failed");
        return 1;
    }
    puts("Data Send\n");

    // Receive a reply from the server
    if((recv_size = recv(s , server_reply , 2000 , 0)) == SOCKET_ERROR)
    {
        puts("recv failed");
    }

    puts("Reply received\n");

    // Add a NULL terminating character to make it a proper string before printing
    server_reply[recv_size] = '\0';
    printf("size: %d\n",recv_size);
    puts(server_reply);

    return 0;
}

Solution

  • Two problems. Firstly, you can't just send the URL by itself; you need to make an HTTP request. The best way to do this is often to use a third-party library like LibCURL, but for very simple cases you might prefer to do it by hand. At the very least you'd need a GET line, a Host: header and a blank line. See the HTTP RFC for how to format a request and parse the response.

    Secondly, if you want to use HTTPS, you can't just send plain text to a socket, there is also an encryption layer. Again, you will need a library. (On Linux I would use OpenSSL or libCURL, which also exist on Windows but there may be other choices there.) By the way, by default HTTP uses port 80 but HTTPS uses port 443.