sending structure client server - Unix

This is a discussion on sending structure client server - Unix ; Hi , I want to send a structure (user defined) for example : struct bank{ int empid; char name[50]; float amount; } per; I want to send this from a client to server on unix.Can any1 tell me how to ...

+ Reply to Thread
Results 1 to 11 of 11

Thread: sending structure client server

  1. sending structure client server

    Hi ,
    I want to send a structure (user defined) for example :

    struct bank{

    int empid;
    char name[50];
    float amount;

    } per;

    I want to send this from a client to server on unix.Can any1 tell me
    how to send this(from client) and read the data at the other end(at
    server).tnx in advance...

  2. Re: sending structure client server

    On Oct 11, 11:19*am, swetha wrote:
    > Hi ,
    > * * * *I want to send a structure (user defined) for example :
    >
    > struct bank{
    >
    > int empid;
    > char name[50];
    > float amount;
    >
    > } per;
    >
    > I want to send this from a client to server on unix.Can any1 tell me
    > how to send this(from client) and read the data at the other end(at
    > server).tnx in advance...


    This is the basic algorithm for a client app, using stream sockets
    (prototyped):

    #include
    #include
    #include
    #include

    struct bank {
    int empid;
    char name[50];
    float amount;
    };

    int
    main(int argc, char *argv[])
    {
    struct addrinfo *aiResult;

    // assuming that argv[1] contains the server's address and argv[2]
    the service...
    int rv = getaddrinfo(argv[1], argv[2],
    &(struct sockaddr) {.ai_family = AF_UNSPEC,
    .ai_socktype =
    SOCK_STREAM},
    &aiResult);
    if (rv != 0)
    // ...handle error...
    exit(EXIT_FAILURE);

    int sockfd;

    for (struct sockaddr *aiNode = aiResult; aiNode != NULL; aiNode =
    aiNode->ai_next) {
    sockfd = socket(aiNode->ai_family,
    aiNode->ai_socktype,
    aiNode->ai_protocol);
    if (sockfd == -1)
    // try next
    continue;

    if (connect(sockfd, aiNode->ai_addr, aiNode->ai_addrlen) == 0)
    // success
    break;

    close(sockfd);
    }

    // send a bank structure...
    if (send(sockfd, (struct bank) {20, "hello", 10.01}, sizeof(struct
    bank), 0) == -1)
    // ...handle error...
    exit(EXIT_FAILURE);

    close(sockfd);
    }

    And this would be the server's:

    // ...
    // Same #includes and struct bank definition
    // ...

    int
    main(int argc, char *argv[])
    {
    struct addrinfo *aiResult;

    // here, argv[1] should contain the service
    int rv = getaddrinfo(NULL, argv[1],
    &(struct sockaddr) {.ai_flags =
    AI_PASSIVE,
    .ai_family = AF_UNSPEC,
    .ai_socktype =
    SOCK_STREAM},
    &aiResult);
    if (rv != 0)
    // ...handle error...
    exit(EXIT_FAILURE);

    int sockfd;

    for (struct sockaddr *aiNode = aiResult; aiNode != NULL; aiNode =
    aiNode->ai_next) {
    sockfd = socket(aiNode->ai_family,
    aiNode->ai_socktype,
    aiNode->ai_protocol);
    if (sockfd == -1)
    // try next
    continue;

    // note: bind(), not connect()
    if (bind(sockfd, aiNode->ai_addr, aiNode->ai_addrlen) == 0)
    // success
    break;

    close(sockfd);
    }

    if (listen(sockfd, 5) == -1)
    // ...handle error...
    exit(EXIT_FAILURE);

    int client = accept(sockfd, NULL, NULL); // we don't wan to know
    about the address...
    if (client == -1)
    // ...handle error...
    exit(EXIT_FAILURE);

    // receive a bank structure
    struct bank b;

    if (recv(sockfd, &b, sizeof(struct bank), 0) != sizeof(struct
    bank))
    // an error occurred or we didn't receive enough data
    exit(EXIT_FAILURE);

    // check what was received
    printf("b.empid == %d\n", b.empid);
    printf("b.name == \"%s\"\n", b.name);
    printf("b.amount == %f\n", b.amount);

    close(client);
    close(sockfd);
    }

    Sebastian


  3. Re: sending structure client server

    s0suk3@gmail.com wrote:
    > On Oct 11, 11:19 am, swetha wrote:
    >> Hi ,
    >> I want to send a structure (user defined) for example :
    >>
    >> struct bank{
    >>
    >> int empid;
    >> char name[50];
    >> float amount;
    >>
    >> } per;
    >>
    >> I want to send this from a client to server on unix.Can any1 tell me
    >> how to send this(from client) and read the data at the other end(at
    >> server).tnx in advance...

    >
    > This is the basic algorithm for a client app, using stream sockets
    > (prototyped):
    >

    The code you posted will only work on a homogeneous network. If either
    the client or sever have a different representation of the struct, all
    bets are off.

    --
    Ian Collins

  4. Re: sending structure client server

    On Oct 11, 5:06*pm, Ian Collins wrote:
    > s0s...@gmail.com wrote:
    > > On Oct 11, 11:19 am, swetha wrote:
    > >> Hi ,
    > >> * * * *I want to send a structure (user defined) for example :

    >
    > >> struct bank{

    >
    > >> int empid;
    > >> char name[50];
    > >> float amount;

    >
    > >> } per;

    >
    > >> I want to send this from a client to server on unix.Can any1 tell me
    > >> how to send this(from client) and read the data at the other end(at
    > >> server).tnx in advance...

    >
    > > This is the basic algorithm for a client app, using stream sockets
    > > (prototyped):

    >
    > The code you posted will only work on a homogeneous network. *If either
    > the client or sever have a different representation of the struct, all
    > bets are off.



    Yes. The example provided is generally unsuitable for more than the
    most trivial learning and experimental applications. Generally, at the
    bare minimum, you'd want to send/receive each field of the structure
    individually, rather than sending the entire structure at once, unless
    you can guarantee that the compiler used to compile both the client
    and server code is always using the same byte alignment for the struct
    you're sending. That would be one of the more common problems. Another
    common problem would be differences in data endian-ness, for example
    when sending a binary integer value from a PC to a PowerPC Mac. That
    can be mitigated by using functions like htons, ntohs and friends.
    Endian-ness also matters with binary floating-point types.

    A less common but still real problem is other differences in binary
    values between the sending and receiving platforms, such as the size
    of an "int" type, internal representation differences (e.g. padding
    bits, etc.), and many other problems that can come up.

    You can cover *most* of your bases by sending structure fields
    individually, always guaranteeing a consistent byte ordering for
    multibyte integer / floating-point values, always using data types
    with consistent sizes (e.g. never use "int", it's size is not
    guaranteed), and at least specifying platform requirements for binary
    value representations (e.g. this protocol sends 2's complement
    integers with bits in order of significance and no padding bits,
    etc.).

    Jason


    >
    > --
    > Ian Collins



  5. Re: sending structure client server

    Ian Collins wrote:
    > s0suk3@gmail.com wrote:
    >> On Oct 11, 11:19 am, swetha wrote:
    >>> Hi ,
    >>> I want to send a structure (user defined) for example :
    >>>
    >>> struct bank{
    >>>
    >>> int empid;
    >>> char name[50];
    >>> float amount;
    >>>
    >>> } per;
    >>>
    >>> I want to send this from a client to server on unix.Can any1 tell me
    >>> how to send this(from client) and read the data at the other end(at
    >>> server).tnx in advance...

    >> This is the basic algorithm for a client app, using stream sockets
    >> (prototyped):
    >>

    > The code you posted will only work on a homogeneous network. If either
    > the client or sever have a different representation of the struct, all
    > bets are off.


    And the solution is to turn the data into a stream of bytes (at the
    sender) and back again (at the receiver), according to some protocol.
    This is similar to defining a file format.

    Not only that, but:


    if (recv(sockfd, &b, sizeof(struct bank), 0) != sizeof(struct
    bank))
    // an error occurred or we didn't receive enough data
    exit(EXIT_FAILURE);


    Is logically wrong for a stream socket. A call to recv() returning less
    than the requested number of bytes should not be considered a failure.

    On a blocking socket, recv() will return when /any/ bytes are available,
    or if/when an error is detected, or if interrupted by a signal. A
    "short" recv() may happen at any time. As an example, it is virtually
    guaranteed for a TCP socket if the requested size is greater than the
    MSS and the link between the endpoints is slow (eg dial-up modem).

    This possibility can be handled by putting the call in a loop, adjusting
    the pointer and requested size in the recv() call according to any data
    previously received.

    Alex

  6. Re: sending structure client server

    On Oct 11, 4:47*pm, Alex Fraser wrote:
    > Ian Collins wrote:
    > > s0suk3@gmail.com wrote:
    > >> On Oct 11, 11:19 am, swetha wrote:
    > >>> Hi ,
    > >>> * * * *I want to send a structure (user defined) for example :

    >
    > >>> struct bank{

    >
    > >>> int empid;
    > >>> char name[50];
    > >>> float amount;

    >
    > >>> } per;

    >
    > >>> I want to send this from a client to server on unix.Can any1 tell me
    > >>> how to send this(from client) and read the data at the other end(at
    > >>> server).tnx in advance...
    > >> This is the basic algorithm for a client app, using stream sockets
    > >> (prototyped):

    >
    > > The code you posted will only work on a homogeneous network. *If either
    > > the client or sever have a different representation of the struct, all
    > > bets are off.

    >
    > And the solution is to turn the data into a stream of bytes (at the
    > sender) and back again (at the receiver), according to some protocol.
    > This is similar to defining a file format.
    >
    > Not only that, but:
    >
    >
    > * * *if (recv(sockfd, &b, sizeof(struct bank), 0) != sizeof(struct
    > bank))
    > * * * * *// an error occurred or we didn't receive enough data
    > * * * * *exit(EXIT_FAILURE);
    >

    >
    > Is logically wrong for a stream socket. A call to recv() returning less
    > than the requested number of bytes should not be considered a failure.
    >
    > On a blocking socket, recv() will return when /any/ bytes are available,
    > or if/when an error is detected, or if interrupted by a signal. A
    > "short" recv() may happen at any time. As an example, it is virtually
    > guaranteed for a TCP socket if the requested size is greater than the
    > MSS and the link between the endpoints is slow (eg dial-up modem).
    >
    > This possibility can be handled by putting the call in a loop, adjusting
    > the pointer and requested size in the recv() call according to any data
    > previously received.


    Of course; that's what's always done with stream sockets. Like I said,
    that was a "basic" algorithm for this kind of stuff; it wasn't
    intended as a complete program.

    One real solution to the whole problem would be what Andrew Gabriel
    suggested. A better solution, IMO, would be to create a protocol
    designed specifically for the needs of your app, or to use an existing
    one, such as HTTP, perhaps by extending it. You could then transmit
    the data as either text (in the headers of the message, for example),
    or as binary (in the body of the message). Of course, sending it as
    binary would lead us back to the same problem: struct representation.
    Suppose we were to extend HTTP in order to send responses containing a
    struct serialized using what Andrew Gabriel suggested. We could add an
    "application/xdr" media type. The response could look like this:

    HTTP/1.1 200 OK
    Content-Type: application/xdr
    Content-Length: 50



    (It should also contain the Date and Server headers, of course :-)

    Sebastian


  7. Re: sending structure client server

    On Oct 11, 9:19*am, swetha wrote:
    > Hi ,
    > * * * *I want to send a structure (user defined) for example :
    >
    > struct bank{
    >
    > int empid;
    > char name[50];
    > float amount;
    >
    > } per;
    >
    > I want to send this from a client to server on unix.Can any1 tell me
    > how to send this(from client) and read the data at the other end(at
    > server).tnx in advance...


    You need a protocol specification first. Do not code a protocol until
    you have made a protocol specification.

    That way, when it doesn't work, one of three things will be the case:

    1) The client doesn't follow the specification, the client is broken.

    2) The server doesn't follow the specification, the server is broken.

    3) Both sides follow the specification, the specification is broken.

    But if you have no specification, you can never figure out what's
    wrong or what needs to be fixed. You can never tell if the client is
    correct or not, because you have nothing to compare it to.

    DS

  8. Re: sending structure client server

    s0suk3@gmail.com writes:
    > On Oct 11, 4:47*pm, Alex Fraser wrote:
    >> Ian Collins wrote:
    >> > s0suk3@gmail.com wrote:
    >> >> On Oct 11, 11:19 am, swetha wrote:
    >> >>> Hi ,
    >> >>> * * * *I want to send a structure (user defined) for example :

    >>
    >> >>> struct bank{

    >>
    >> >>> int empid;
    >> >>> char name[50];
    >> >>> float amount;

    >>
    >> >>> } per;


    [...]

    >> > The code you posted will only work on a homogeneous network. *If either
    >> > the client or sever have a different representation of the struct, all
    >> > bets are off.

    >>
    >> And the solution is to turn the data into a stream of bytes (at the
    >> sender) and back again (at the receiver), according to some protocol.
    >> This is similar to defining a file format.


    [...]

    > One real solution to the whole problem would be what Andrew Gabriel
    > suggested. A better solution, IMO, would be to create a protocol
    > designed specifically for the needs of your app, or to use an existing
    > one, such as HTTP, perhaps by extending it. You could then transmit
    > the data as either text (in the headers of the message, for example),
    > or as binary (in the body of the message). Of course, sending it as
    > binary would lead us back to the same problem: struct
    > representation.


    IOW, 'using HTTP' by itself would add nothing specifically helpful
    regarding the problem of 'data transmission' between (potentially)
    heterogenous computing environments (while 'using XDR-encoding'
    would). That's because HTTP is an application protocol designed to
    communicate meta-information necessary to build distributed
    hypermedia-systems, eg by providing a 'device-independent' way to
    specify a particulary named 'ressource' and some operation supposed
    to be done with it (for instance, GET or PUT it). The 'how everyone
    else does it' approach to constructing any server application would be
    'use a programmable HTTP-server' and send documents conforming to some
    application-specific XML DTD and the 'first level workaround' for the
    problem that
    XMLcontainslots
    of
    trash.


    would be to make the communicating computers spend even more time with
    communication meta-processing by compressing and decompressing the
    message in order to temporarily get rid of at least some of the
    redundant information added by the encoder.

    It is ususally easier to just define a binary message format and use
    encoding and decoding routines to convert it to/from some 'native
    representation' a program can easily deal with (I have just designed a
    specific binary data format for exchanging data sets composed of
    sequences of records with members of specific types and the written
    specification of the data format plus the (C-)code which decodes the
    transport format into linked C structs contains less text than the
    introductory remarks of the XML-specification [slight hyperbole :->]).

    A general tip for anything like this would be "include a way to
    distinguish between multiple revisions/ versions of the protocol, so
    that a 'newer' server can offer other/ additional features to 'new'
    clients while still being able to serve old clients".





  9. Re: sending structure client server

    On Oct 12, 1:57*pm, Rainer Weikusat wrote:

    [...]
    > It is ususally easier to just define a binary message format
    > and use encoding and decoding routines to convert it to/from
    > some 'native representation' a program can easily deal with


    It's usually easier to define and implement something totally
    new than to use existing software? I don't think so. I can't
    say I really like XML, but it does have the advantage that all
    of the tools needed for conversion are readily available. While
    this is probably true for other protocols as well (I'd be
    surprised if there wasn't an Open Source implementation of XDR
    somewhere), they're certainly not as easy to find.

    [...]
    > A general tip for anything like this would be "include a way
    > to distinguish between multiple revisions/ versions of the
    > protocol, so that a 'newer' server can offer other/ additional
    > features to 'new' clients while still being able to serve old
    > clients".


    That is an important (and often forgotten) point. Which speaks
    for some sort of "self-identifying" format: XML, BER, etc. (A
    self identifying format allows adding fields without breaking
    existing implementations.)

    --
    James Kanze (GABI Software) email:james.kanze@gmail.com
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


  10. Re: sending structure client server

    James Kanze writes:

    > On Oct 12, 1:57*pm, Rainer Weikusat wrote:
    >
    > [...]
    >> It is ususally easier to just define a binary message format
    >> and use encoding and decoding routines to convert it to/from
    >> some 'native representation' a program can easily deal with

    >
    > It's usually easier to define and implement something totally
    > new than to use existing software? I don't think so. I can't
    > say I really like XML, but it does have the advantage that all
    > of the tools needed for conversion are readily available. While
    > this is probably true for other protocols as well (I'd be
    > surprised if there wasn't an Open Source implementation of XDR
    > somewhere), they're certainly not as easy to find.


    An XDR implementation is pretty much guaranteed to be available on
    anything resembling Unix. It is used by, for instance, the NFS
    protocol. The original implementation by Sun is open source, and is
    included in e.g. glibc and, not surprisingly, Solaris.

    Friends don't let friends use XML.

    --
    Mĺns Rullgĺrd
    mans@mansr.com

  11. Re: sending structure client server

    James Kanze writes:
    > On Oct 12, 1:57*pm, Rainer Weikusat wrote:
    >
    > [...]
    >> It is ususally easier to just define a binary message format
    >> and use encoding and decoding routines to convert it to/from
    >> some 'native representation' a program can easily deal with

    >
    > It's usually easier to define and implement something totally
    > new than to use existing software? I don't think so.


    That's why I wrote 'it is usually easier to define an application
    specific message format, including serialization and deserialzation
    routines, than to define an application specific XML-format and the
    associated serialization and deseriaization routines. For the
    particular example I was giving, the format specification has 121
    lines of text and the decoding 'software' adds 372 lines of C to that.
    The 'introductory parts' of the 'XML 1.0 specification' (fourth
    edition) figure at 314 lines of text.

    This means that, in addition to defining your data format and writing
    the code to transform the internal representation of the program to
    and from it, there will be at least 61 pages of XML documentation,
    written in 'markup chinese' that will have to be read, understood and
    remembered (this is likely a much to optimistic assumption, because
    'all of XML' consists of at least six such documents). The practical
    effect of undertaking this technically completely useless semantic
    expedition is the ability to define a data format such that it has
    spectacularly bad properties in any possible category such a format
    could be judged in: The SDU/PDU ratio is lousy, it is highly
    redundant, not human-readable because it resembles machine-oriented
    structured data, not machine-readable, because it isn't structured,
    but a character stream and so forth.

    The only thing which can be saved in this way is the 'mental effort'
    to come up with a different data representation convention that
    data when designing a text format. Ever had to deal with
    bind? Congratulations, you now know already two of them.

    [...]

    >> A general tip for anything like this would be "include a way
    >> to distinguish between multiple revisions/ versions of the
    >> protocol, so that a 'newer' server can offer other/ additional
    >> features to 'new' clients while still being able to serve old
    >> clients".

    >
    > That is an important (and often forgotten) point. Which speaks
    > for some sort of "self-identifying" format: XML, BER, etc. (A
    > self identifying format allows adding fields without breaking
    > existing implementations.)


    I have no idea what a 'self-identifying format' should be (since the
    'format' is passive and must necessarily be 'indentified' by some
    software, it doubt that a sensible definition is even possible). 'XML'
    is still a markup language. BER (basic encoding rules) is another
    general, binary data encoding scheme, this time the 'historical' (ie
    oldest) encoding scheme associated with ASN.1, which I would certainly
    prefer over XML for machine-machine communication any time, but that's
    about the most positive thing which can be said about it (one should
    IMHO at least be familiar with its basic principles, though). It is
    still a lot more complicated than needed for most situations (eg when
    I always send a sequence of records composed of sequences of typed
    fields, I don't need an explicit general sequence type) and has a
    couple of other problems, eg it cannot efficiently be processed by
    CPUs lacking an instruction to count leading zeros in a machine word
    (eg ARMv4 CPUs).

    Did you mean a 'self-delimiting format', ie one where the structure of
    a message can be analysed without looking at the data content? This is
    (obviously) possible in XML (especially since it doesn't have a
    structure :->) and is achieved in BER by always transmitting 'value
    type' and 'length of the encoded representation of type' separately.
    But in reality, the structure of a message with unknown (and
    therefore, unprocesable) content is of little use in an application
    intended to process this content (and not the structure itself).

    It is possible to define an extensible format such that new information
    can be added in a way that the meaning of old information remains
    valid. A simple example for that would be TCP options like SACK or
    timestamp: An implementation which doesn't know about a TCP option can
    ignore it and, while not being able to expoit any new features, still
    use any of the 'old' features known to it. I was thinking about
    something much simpler, though: Put a protocol/ format version
    number into messages, so that clients using different software
    versions can be distinguished by examining a 'well-known' part of a
    message.

+ Reply to Thread