Search code examples
csocketsclient

Beginner's Socket Programming in C


I have just started learning socket programming and am finding it pretty interesting. Currently I am making the server and the client on the same computer and hence I can have the ip address as the loopback address, 127.0.0.1 and everything seems to work fine!!

But now I was thinking of having two computers and doing the thing.. I have the following questions

  1. Say one computer is Server and another is Client. Now, should the server code reside on the server computer and the Client code on the client one?
  2. In the server code when we are providing the ip address for bind(), it should be the ip address of the system that we can find through ipconfig or it should still remain the loopback address?
  3. In the client code, I guess the ip address of the destination should be that of the server computer right??
  4. And the last and the most important thing, HOW DO I CONNECT THE TWO COMPUTERS??

I am attaching the simple server and client message passing code that I started out with. Kindly guide me through the changes that I need to make..

SERVER CODE

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>

#define MYPORT 3500

int main()
{
    int sockfd;
    int clientfd;
    int bytes_read;
    char buf[100];
    int struct_size;
    struct sockaddr_in my_addr;
    struct sockaddr_in con_addr;
    
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    
    my_addr.sin_family = AF_INET;
    my_addr.sin_port = htons(MYPORT);
    my_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    my_addr.sin_zero[8]='\0';

    bind(sockfd, (struct sockaddr*)&my_addr, sizeof(struct sockaddr));

    listen(sockfd,5);
    
    struct_size = sizeof(con_addr);
    clientfd = accept(sockfd, (struct sockaddr*)&con_addr, &struct_size);

    bytes_read = read(clientfd, buf, 100);
    buf[bytes_read] = '\0';
    printf("Message from client:%d is %s \n",clientfd, buf);

    close(sockfd);
    close(clientfd);
}

CLIENT CODE

#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<fcntl.h>
#include<string.h>
#include<stdio.h>

#define DESTPORT 3500

int main()
{

    struct sockaddr_in dest_addr;
    
    int sockfd = socket(AF_INET,SOCK_STREAM,0);

    dest_addr.sin_family = AF_INET;
    dest_addr.sin_port = htons(DESTPORT);
    dest_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    dest_addr.sin_zero[8]='\0';

    connect(sockfd,(struct sockaddr*)&dest_addr, sizeof(struct sockaddr));

    char msg[100];
    printf("Enter you message: ");
    gets(&msg); 
    
    int w = write(sockfd, msg, strlen(msg));
    
    close(sockfd);
    printf("Client Dying.....\n"); 

    return 0;
}

Solution

  • Server should bind to 0.0.0.0 (any) unless you're trying to restrict access (and in that case you should really use a firewall rather than port binding). The correct way is actually:

    struct addrinfo *ai, hints = { .ai_flags = AI_PASSIVE };
    if (getaddrinfo(0, "1234", &hints, &ai)) goto error;
    int fd = socket(ai->ai_family, SOCK_STREAM, 0);
    bind(fd, ai->ai_addr, ai->ai_addrlen);
    

    Add some error checking, of course. Replace "1234" with your port number.