Find the answer to your Linux question:
Page 1 of 2 1 2 LastLast
Results 1 to 10 of 11
Hi I have a problem here ... I need to read data from a socket but it should be always listening because data arrives continuously .. I thought something like ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Just Joined! SingleFemaleLawyer's Avatar
    Join Date
    Jul 2010
    Posts
    28

    Read from socket


    Hi I have a problem here ... I need to read data from a socket but it should be always listening because data arrives continuously .. I thought something like this would do it but it doesn't work .... I already set the socket options before

    Code:
     char databuf[1024];
            int datalen = sizeof(databuf);
            if(read(sd, databuf, datalen) < 0)
            {
                perror("Error en lectura del buffer");
                close(sd);
                exit(1);
            }
            else
            {
                printf("Reading datagram message...OK.\n");
                printf("Mensaje recibido: \"%s\"\n", databuf);
            }

  2. #2
    Just Joined!
    Join Date
    Feb 2006
    Posts
    13
    I believe the question and code you posted is not matching.

    And from what you said, you dont need socket to be listen for reading.

    Once connected, the other socket will keep on writting into the buffer and your socket has to read from it.

    Hope this helps.

  3. #3
    Linux Engineer Kloschüssel's Avatar
    Join Date
    Oct 2005
    Location
    Italy
    Posts
    773
    You fill the buffer only once and not to the end of the stream. Generally such code looks like:

    Code:
    int socketDescriptor;
    // init socketDescriptor (omited)
    // alloc buffer
    byte* buffer = (byte*) malloc(sizeof(byte) * LENGTH);
    int readLength = -1;
    while((readLength = read(socketDescriptor, buffer, LENGTH)) >= 0) {
       // process data in the buffer
    }
    if(readLength < 0) {
       // error
    }
    // dispose
    close(socketDescriptor);
    free(buffer);
    Last edited by Kloschüssel; 08-24-2010 at 09:20 AM.

  4. #4
    Just Joined! SingleFemaleLawyer's Avatar
    Join Date
    Jul 2010
    Posts
    28
    Thank you, it's been a while since i used sockets for the last time and i dont remember a lot of things.

    So, with this line it should read the socket (sd) and put data into databuf ?
    read(sd, databuf, datalen)

    what will happen when the buffer is full ?? I dont need a while or for loop to have it reading ?

    Edit: @Kloschüssel We posted at the same time, I'l take a look at taht code now, it looks good

  5. #5
    Linux Engineer Kloschüssel's Avatar
    Join Date
    Oct 2005
    Location
    Italy
    Posts
    773
    read fills exactly the amount of bytes specified into the buffer. make sure to not write more bytes than the buffers size (commonly referenced as buffer overflow).

    what will happen when the buffer is full ??
    This is wanted behaviour.

    I dont need a while or for loop to have it reading ?
    indeed you need it cause you don't know how much data will be sent through the socket, but greedily want to get all the data. the buffer on the other hand is fixed size, so you cannot store all the data into the buffer but will have to iterate over it. above example is a implementation that would create some kind of hash over the received data:

    Code:
    byte hash = 0;
    while((readLength = read(socketDescriptor, buffer, LENGTH)) >= 0) {
       // process data in the buffer
       for(int i=0; i<readLength; i++) {
          hash = hash ^ buffer[i];
          hash = hash << 1;
       }
    }
    Note that i read only that amount of data that was truely read from the socket (which is buffer[0..readLength]) and not the whole buffer (which would be buffer[0..LENGTH]).

    Of course you can also copy the read data somewhere else using for example memcpy, and of course using memcpy you wouldn't need to iterate over the received data but copy exactly the information you need.

    Code:
    byte hash = 0;
    int slice=0;
    byte** target;
    while((readLength = read(socketDescriptor, buffer, LENGTH)) >= 0) {
       // process data in the buffer
       target = (byte**) realloc(sizeof(byte*) * (slice+1));
       target[slice] = (byte*) malloc(sizeof(byte) * (readLength+1));
       memcpy(target[slice], buffer, readLength);
       slice++;
       // hash it
       for(int i=0; i<readLength; i++) {
          hash = hash ^ buffer[i];
          hash = hash << 1;
       }
    }
    Please note that all this here is just written down from mind and UNTESTED CODE.
    Last edited by Kloschüssel; 08-24-2010 at 09:19 AM.

  6. #6
    Just Joined! SingleFemaleLawyer's Avatar
    Join Date
    Jul 2010
    Posts
    28
    Hi ! Thanks for the help, I'm sorry I didn't reply before I have a couple of days off work Here's what I tested based on what you wrote
    Code:
    int readLength = -1;
            printf("\nReading from socket");
    
            try{
            while((readLength=read(sd, dbuffer, dblength)) >=0){
                //some data processing here when it works
                cout << readLength <<endl;
                printf(dbuffer);
            }
            if(readLength < 0){
                printf("\nError buffer empty\n");
            }
    
            close (sd);
            printf("\nReading .... OK\n");}
            catch(unsigned int a){
                perror("Error reading");
                close(sd);
            }

    And this is the output :

    PHP Code:
    Reading from socket
    Error buffer 
    empty
    Reading .... OK 
    I'm guessing I'm not receiving packets because the reading part looks good to me .. or maybe using recv() ? (I dont really know how to use it though)

    This is what I use to configure the socket , I'm hoping to get multicast UDP data :

    Code:
        struct sockaddr_in mysocket;
        struct ip_mreq group;
        int sd;
        int dblength;
        char dbuffer[1024];
        int reuse = 1;
    
    try{
    	sd = socket(AF_INET, SOCK_DGRAM, 0);
            setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse));
               
            memset((char *) &mysocket, 0, sizeof(mysocket));
            misocket.sin_family = AF_INET;
            misocket.sin_port = htons((unsigned int)multicastport.c_str());
            misocket.sin_addr.s_addr = htonl(INADDR_ANY); 
        
        bind(sd, (struct sockaddr*)&misocket, sizeof(misocket));
              
        group.imr_multiaddr.s_addr = inet_addr(multicastaddress.c_str());
        group.imr_interface.s_addr = inet_addr("192.168.0.8");
                    setsockopt(sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&group, sizeof(group));
              }
    Using Wireshark and the server's log I can see that the UDP data is sent to the correct multicast address & port, the ones that I bind my socket to, so the problem is definitely with my reading

  7. #7
    Linux Engineer Kloschüssel's Avatar
    Join Date
    Oct 2005
    Location
    Italy
    Posts
    773
    *hm* Too much time passed by since I last wrote socket communication. Sorry, can't help you any further. You may need to use rcv instead of read, but I just don't know. Happy coding!

  8. #8
    Just Joined! SingleFemaleLawyer's Avatar
    Join Date
    Jul 2010
    Posts
    28
    You've done more than enough !! Thank you !! I keep investigating Let's see if someone comes up with the magic idea haha because I've checked every single example that I have found on the net the last 4 days and can't make my program work !! and it is soooo simple !!!

  9. #9
    Linux Engineer Kloschüssel's Avatar
    Join Date
    Oct 2005
    Location
    Italy
    Posts
    773
    If the code is ok, it may be something else.

    * got a server instance ?
    * is server instance up&listening before client starts ?
    * firewall ?

    Depending on your network environment (i.e. scholastic, university, ..) there may be some network policies that block your traffic? In that case connect the two computers with a wire and set up the connection statically. At least you then have a predictable and safe environment to test. If then your code works, you can migrate to a unsafe environment and improve functionality such that it works also there.

  10. #10
    Just Joined! SingleFemaleLawyer's Avatar
    Join Date
    Jul 2010
    Posts
    28
    This is the situation haha I only post it for your curiosity as you have been dealing with this problem with me ^^

    I have to use a server (the one that sends the video packets) that has not been implemented by me, and more, I have no access to it !! I know it is sending the UDP data because I can see it with wireshark, and it looks ok.

    So I wrote a client (receives data) that looks ok, but doesn't work with that server somehow.

    Tired, I just finised writing my own server (sends just characters , not video), and it communicates ok with the client that i wrote in any network !!!

    As I say, the problems always come with the code that you dont write by yourself, when you copy&paste or like in this case when you have to use someone's work by obligation !!!

    I'll write again if this ever gets solved !!

    Best regards, Jess

Page 1 of 2 1 2 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •