Unix/Linux Go Back    


IP Networking Learn TCP/IP, Internet Protocol, Routing, Routers, Network protocols in this UNIX and Linux forum.

A Basic example of socket programming in C

IP Networking


Tags
ansi c, client, server, socket programming

Reply    
 
Thread Tools Search this Thread Display Modes
    #1  
Old Unix and Linux 06-15-2017   -   Original Discussion by yifangt
yifangt yifangt is offline VIP Member  
UNIX.COM VIP Member
 
Join Date: Sep 2009
Last Activity: 23 November 2017, 12:09 PM EST
Location: Saskatchewan, Canada
Posts: 512
Thanks: 329
Thanked 7 Times in 7 Posts
A Basic example of socket programming in C

Hello,
I have a question about socket programming
The question was a homework of this university of past (2011?) course.
The server is simulating a sensor that provides readings of temperature, light and humidity (temp.dat, light.dat, humid.dat) each with single column of number, one per row.

Code:
temp.dat:
60
59
58
57
......
light.dat:
40
50
20
30
......
humid.dat:
1
2
3
4
......

The server will open each file, read in all sensor values, and serve every request from the client. If a client requests temperature, the server will return a certain temperature sample from temp.dat according to the time of the connection. Starting from the first value of temp.dat when a connection is established, every second the server should return the next value in temp.dat upon request. If EOF is reached, the server should wraps around and start from the beginning of the file again. Display readings to the screen:
Code:
Connected to server!
Data returned by the server:
TEMPERATURE = 60 HUMIDITY = 40 LIGHT = 1
Data returned by the server:
TEMPERATURE = 59 HUMIDITY = 50 LIGHT = 2
Data returned by the server:
TEMPERATURE = 58 HUMIDITY = 20 LIGHT = 3
......  ......  ......

I have attached the code in C for server and client parts, but I am quite obscure about reading the 3 files in the server side and display in the client side by request.
This is NOT my homework for any class, but for self study to understand basic server-client communication of socket programming in C.

Any suggestion is greatly appreciated and pseudo code is fine.

Thanks a lot!
Attached Files
File Type: txt conEchoServer.txt (1.7 KB, 4 views)
File Type: txt echoClient.txt (1.4 KB, 5 views)
Sponsored Links
    #2  
Old Unix and Linux 06-16-2017   -   Original Discussion by yifangt
Corona688 Corona688 is offline Forum Staff  
Mead Rotor
 
Join Date: Aug 2005
Last Activity: 23 November 2017, 4:41 PM EST
Location: Saskatchewan
Posts: 22,523
Thanks: 1,154
Thanked 4,275 Times in 3,948 Posts
Here's code which reads files in order when given as commandline arguments:


Code:
#include <stdio.h>

char line[4096];
char **files=NULL;
int filenum=0;
FILE *file=NULL;

// Close current file if any, open next from files[]
FILE *next_file() {
        if(file)
        {
                fclose(file);
                file=NULL;
        }

        if(files[filenum] == NULL) return(file=NULL); // out of files
        return(file=fopen(files[filenum++], "r"));
}

char *next_line(void) {
        // Keep trying to get a line until we get a line or run out of files
        while(1)
        {
                // If something is open, try and read it.
                // If we read it, return the line.
                if(file && fgets(line, 4096, file)) return(line);

                // If we're out of files, return error immediately.
                if(files[filenum] == NULL) return(NULL); // out of files

                // Close current and open next file
                next_file(files);
        }

        return(line);
}

void main(int argc, char *argv[]) {
        // get list of files from argv.
        // argv is organized like { "programname", "arg1", "arg2", "arg3", NULL }
        files=argv;
        filenum=1;      // valid arguments in argv[] start at 1

        while(next_line())
        {
                fputs(line, stdout);
                sleep(3);
        }
}

Being able to call next_line repeatedly without worrying about which file is open should make it easier.
The Following User Says Thank You to Corona688 For This Useful Post:
yifangt (06-16-2017)
Sponsored Links
    #3  
Old Unix and Linux 06-16-2017   -   Original Discussion by yifangt
yifangt yifangt is offline VIP Member  
UNIX.COM VIP Member
 
Join Date: Sep 2009
Last Activity: 23 November 2017, 12:09 PM EST
Location: Saskatchewan, Canada
Posts: 512
Thanks: 329
Thanked 7 Times in 7 Posts
Thanks!
Your code opens the file sequentially, but the output shows three values in a row, which seems to me the three files are opened simultaneously:

Code:
Connected to server! 
Data returned by the server: 
TEMPERATURE = 60 HUMIDITY = 40 LIGHT = 1 
Data returned by the server: 
TEMPERATURE = 59 HUMIDITY = 50 LIGHT = 2 
Data returned by the server: 
TEMPERATURE = 58 HUMIDITY = 20 LIGHT = 3

1) Is this right? I was thinking pthreads too, but not sure pthreads is the correct way.
2) I assumed this display part is piped in the client side. Can this part be embedded to the echoClient program, i.e. integrated this part into the echoClient program?

Thanks again!

Last edited by yifangt; 06-16-2017 at 06:04 PM..
    #4  
Old Unix and Linux 06-16-2017   -   Original Discussion by yifangt
Corona688 Corona688 is offline Forum Staff  
Mead Rotor
 
Join Date: Aug 2005
Last Activity: 23 November 2017, 4:41 PM EST
Location: Saskatchewan
Posts: 22,523
Thanks: 1,154
Thanked 4,275 Times in 3,948 Posts
1) No. It just reads lines.
2) No. It just prints lines.

Unless your current code is radically different from what it was before, that is. Show your code please.
Sponsored Links
    #5  
Old Unix and Linux 06-16-2017   -   Original Discussion by yifangt
yifangt yifangt is offline VIP Member  
UNIX.COM VIP Member
 
Join Date: Sep 2009
Last Activity: 23 November 2017, 12:09 PM EST
Location: Saskatchewan, Canada
Posts: 512
Thanks: 329
Thanked 7 Times in 7 Posts
Here is my code not using pthreads:

Code:
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <arpa/inet.h>

#define MAXLINE 4096   /*max text line length*/
#define SERV_PORT 3000 /*port*/

FILE *pF_temperature = NULL;
FILE *pF_light = NULL;
FILE *pF_humidity = NULL;

int main(int argc, char **argv) 
{
 int sockfd;
 struct sockaddr_in servaddr;
  char sendline[MAXLINE], recvline[MAXLINE];

  char line1[MAXLINE];
  char line2[MAXLINE];
  char line3[MAXLINE];

 //basic check of the arguments
 //additional checks can be inserted
 if (argc != 5) {
  perror("Usage: TCPClient <IP address of the server"); 
  exit(1);
 }
    
 //Create a socket for the client
 //If sockfd<0 there was an error in the creation of the socket
 if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) <0) {
  perror("Problem in creating the socket");
  exit(2);
 }
    
 //Creation of the socket
 memset(&servaddr, 0, sizeof(servaddr));
 servaddr.sin_family = AF_INET;
 servaddr.sin_addr.s_addr= inet_addr(argv[1]);
 servaddr.sin_port =  htons(SERV_PORT); //convert to big-endian order
    
 //Connection of the client to the socket 
 if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr))<0) {
  perror("Problem in connecting to the server");
  exit(3);
 }

    pF_temperature = fopen(argv[2], "r");
    pF_light = fopen(argv[3], "r");
    pF_humidity = fopen(argv[4], "r");

    if ((pF_temperature == NULL) || (pF_light == NULL) || (pF_humidity == NULL))
    {
      perror("Error: Can not open the three files!");
      return -1;
    }

/*while (fgets(sendline, MAXLINE, stdin) != NULL) {         */
 while ((fgets(line1, MAXLINE, pF_temperature) != NULL) &&
        (fgets(line2, MAXLINE, pF_light) != NULL) &&
        (fgets(line3, MAXLINE, pF_humidity) != NULL)) 
    {
    line1[strcspn(line1, "\r\n")] = 0;        //remove newline
    line2[strcspn(line2, "\r\n")] = 0;        //remove newline
    line3[strcspn(line3, "\r\n")] = 0;        //remove newline

    strcat(sendline, "TEMPERATURE = ");
    strcat(sendline, line1);
    
    strcat(sendline, "\tLIGHT = ");
    strcat(sendline, line2);
    
    strcat(sendline, "\tHUMIDITY = ");
    strcat(sendline, line3);
    
    strcat(sendline, "\n");        //add extra newline for one row
    
    send(sockfd, sendline, strlen(sendline), 0);
        
  if (recv(sockfd, recvline, MAXLINE, 0) == 0){
   //error: server terminated prematurely
   perror("the server terminated prematurely"); 
   exit(4);
  }

  printf("%s\n", "String received from the server: ");
  fputs(recvline, stdout);

} 
 exit(0);
}

I gave it try with:

Code:
$./a.out 192.168.1.34 temperature.dat light.dat humidity.dat

I had redundant output of the whole dataset instead of line by line.

Code:
String received from the server: 
TEMPERATURE = 60    LIGHT = 1    HUMIDITY = 100
TEMPERATURE = 59    LIGHT = 2    HUMIDITY = 150
TEMPERATURE = 58    LIGHT = 3    HUMIDITY = 120
TEMPERATURE = 57    LIGHT = 4    HUMIDITY = 130
TEMPERATURE = 56    LIGHT = 5    HUMIDITY = 140
TEMPERATURE = 55    LIGHT = 6    HUMIDITY = 120
......

The repeat number happened to be the same number of records. Looks like the while-loop is wrong. Spent a couple of hours debugging, no luck.

Last edited by yifangt; 06-16-2017 at 09:51 PM..
Sponsored Links
    #6  
Old Unix and Linux 06-19-2017   -   Original Discussion by yifangt
Corona688 Corona688 is offline Forum Staff  
Mead Rotor
 
Join Date: Aug 2005
Last Activity: 23 November 2017, 4:41 PM EST
Location: Saskatchewan
Posts: 22,523
Thanks: 1,154
Thanked 4,275 Times in 3,948 Posts
It sends humidity, temperature, and light as one line because you read from all three:


Code:
 while ((fgets(line1, MAXLINE, pF_temperature) != NULL) &&
        (fgets(line2, MAXLINE, pF_light) != NULL) &&
        (fgets(line3, MAXLINE, pF_humidity) != NULL))

...then remove newlines from all three:

Code:
    line1[strcspn(line1, "\r\n")] = 0;        //remove newline
    line2[strcspn(line2, "\r\n")] = 0;        //remove newline
    line3[strcspn(line3, "\r\n")] = 0;        //remove newline

...then concatenate all three with labels and tabs inbetween:


Code:
    strcat(sendline, "TEMPERATURE = ");
    strcat(sendline, line1);

    strcat(sendline, "\tLIGHT = ");
    strcat(sendline, line2);

    strcat(sendline, "\tHUMIDITY = ");
    strcat(sendline, line3);

Then send all three:


Code:
send(sockfd, sendline, strlen(sendline), 0);

You are not using my code at all.

Last edited by Corona688; 06-19-2017 at 12:13 PM..
Sponsored Links
    #7  
Old Unix and Linux 06-19-2017   -   Original Discussion by yifangt
yifangt yifangt is offline VIP Member  
UNIX.COM VIP Member
 
Join Date: Sep 2009
Last Activity: 23 November 2017, 12:09 PM EST
Location: Saskatchewan, Canada
Posts: 512
Thanks: 329
Thanked 7 Times in 7 Posts
I am not using yours as your code sends the three file sequentially, but the required output sends three columns in a row, one at a time. That's why I concatenate three lines into one.

Code:
Connected to server!  
Data returned by the server:  
TEMPERATURE = 60 HUMIDITY = 40 LIGHT = 1  
Data returned by the server:  
TEMPERATURE = 59 HUMIDITY = 50 LIGHT = 2  
Data returned by the server:  
TEMPERATURE = 58 HUMIDITY = 20 LIGHT = 3

Your code sends the files one after another.
If I treat the three items (temperature, light, humidity) as a single intact record, then your output seems different from the sample output format, whereas my way seems to be what is required, except the following problems:
1)The whole dataset is output all at once, instead of individual record (3 numbers in a row);
2)The whole dataset is output in the way of 1) 30 times in total (which is exactly the total record numbers), that's what should be fixed.
Not sure if I missed some of your points. Thanks.
Sponsored Links
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Linux More UNIX and Linux Forum Topics You Might Find Helpful
Thread Thread Starter Forum Replies Last Post
Socket programming Gopi Krishna P UNIX for Advanced & Expert Users 4 04-15-2010 10:37 AM
socket programming Gopi Krishna P UNIX for Advanced & Expert Users 2 02-26-2010 02:24 AM
basic socket programming radhakuna Programming 4 07-10-2009 01:34 AM
socket programming damn_bkb IP Networking 6 11-19-2006 02:10 AM
Socket Programming socket soshell Programming 2 06-29-2004 08:49 AM



All times are GMT -4. The time now is 08:46 AM.