3

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;
}
Adam
  • 2,726
  • 1
  • 9
  • 22
sachin11
  • 1,087
  • 3
  • 13
  • 17

4 Answers4

4

1) Correct.

2) On the server side you can bind to 0.0.0.0 which means "all (IPv4) interfaces".

3) Yes, you are right.

4) Most commonly through an Ethernet switch (or a cross-over Ethernet cable but those are harder to find).

florin
  • 13,986
  • 6
  • 46
  • 47
2

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.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
  • Solves my case just the way I wanted it to.. Thanks a ton :-) Can you suggest some good resource to read up about the modern socket programming?? – sachin11 Apr 26 '11 at 14:52
  • Basically the man pages (or POSIX documentation, here: http://pubs.opengroup.org/onlinepubs/9699919799/functions/getaddrinfo.html) for `getaddrinfo`, `getnameinfo`, `socket`, `bind`, `connect`, `listen`, `accept`, `sendto`, `recvfrom`, and `select` is just about all you need. All the complexity you see in older examples and tutorials is merely legacy baggage and a detriment to IPv6 support and portability. – R.. GitHub STOP HELPING ICE Apr 26 '11 at 14:55
  • Why are you not specifying a port anywhere? – JeremyP Apr 26 '11 at 15:08
  • Stupid mistake. Fixed it. Of course you could let `bind` assign you a port number, then use `getsockname` and `getnameinfo` to record it and publish it for clients to use. – R.. GitHub STOP HELPING ICE Apr 26 '11 at 15:27
  • 1
    When you use `getaddrinfo()` you should always loop through all the results and create one socket per listening address. If you just want to do IPv4 *any* address for simplicity, there's no reason to use `getaddrinfo()` in the first place. Your code can lead to surprising situations depending on the system configuration. – Pavel Šimerda Mar 09 '16 at 17:26
  • My hope was to get the IPv6 any address if IPv6 is supported/configured, and otherwise IPv4. But then yes, some broken systems are configured such that the IPv6 any address can't accept v4 connections... So looping and binding all is probably best. – R.. GitHub STOP HELPING ICE Mar 09 '16 at 18:24
0

127.0.0.1 is localhost the loopback address for the machine you are currently on. You probably want to change that to a real ip in the client, if you use two separate boxes.

Yes, the client is usually, but not always, on another physical box from the server. You can just run both pieces on omne box if you want

jim mcnamara
  • 16,005
  • 2
  • 34
  • 51
  • Thank you Sir.. So, I change the ip address in the client code to the ip address of the server machine.. Fine.. But what do I do to the ip address on the server code, here, my_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); – sachin11 Apr 26 '11 at 14:44
  • 1
    You should never have to poke at `sin_addr.s_addr`, etc. manually. This is a bad kind of socket programming from the early 90s that will bring you lots of headaches and make it hard to support IPv6. See my answer for the modern way to bind a socket for listening. – R.. GitHub STOP HELPING ICE Apr 26 '11 at 14:47
0

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??

I don't think I understand this one in the right perspective...lol.If your clientside code is in serverside,how could you allocate any memory lots or invoke stuff on the client computer?

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??

what we have on man page:

 int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

"bind() assigns the address specified to by addr to the socket referred to by the file descriptor sockfd. addrlen specifies the size, in bytes, of the address structure pointed to by addr. Traditionally, this operation is called "assigning a name to a socket". It is normally necessary to assign a local address using bind() before a SOCK_STREAM socket may receive connections (see accept(2))."

In your case,I suppose,127.0.0.1 is what you are looking for.In a nutshell,the address you talked about is more likely to be the one you set up to server_addr structure.

3) In the client code, I guess the ip address of the destination should be that of the server computer right??

Yes.

4) And the last and the most important thing, HOW DO I CONNECT THE TWO COMPUTERS??

Sounds like a classic chat room application. As far as I know(I am a novice...),UDP(User Datagram Protocol) programming & APIs is worth a shot,probably.If you would like to stick to TCP/IP,two arbitrary computers essentially not connect to each other but both stay a hold with the server and the server will be the cornerstone between them.

What's more,I looked into some socket man page:

 int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

"The connect() system call connects the socket referred to by the file descriptor sockfd to the address specified by addr. The addrlen argument specifies the size of addr. The format of the address in addr is determined by the address space of the socket sockfd; see socket(2) for further details."

I think this explains your question in a theoretical manner perfectly.

jasonkim
  • 696
  • 1
  • 7
  • 27
  • I m new to socket programming, is this concept correct, provided we can connect the server and client computer together perhaps via a LAN, or WAN, then server and client resides in two separate computers, and the server can yet allocate some memory on the server side computer, for the client.I m thinking its conceptually correct, please but correct me, if I m wrong – Dulangi_Kanchana Nov 07 '19 at 23:00