distributed programming---lab1(basic communication of server and client)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了distributed programming---lab1(basic communication of server and client)相关的知识,希望对你有一定的参考价值。

socket() creates an endpoint for communication and returns a file
       descriptor that refers to that endpoint.


The lab is about basic communication of server and client.

The server is iterative server which only serves one client at a time.

The socket has the indicated type, which specifies the communication
       semantics.  2 common types are:       SOCK_STREAM     Provides sequenced, reliable, two-way, connection-
                       based byte streams.  An out-of-band data transmission
                       mechanism may be supported.       SOCK_DGRAM      Supports datagrams (connectionless, unreliable
                       messages of a fixed maximum length).
       SOCK_DGRAM as the type gets you a UDP socket.  You can encapsulate 
UDP in TCP of course, but you‘d have to handle the UDP part in 
userspace.  Whether something is reliable depends on the protocol on the
 wire.  If you use TCP, it is reliable; UDP is not.
To create a UDP socket:
int s;
s = socket(AF_INET, SOCK_DGRAM, 0);
To create a TCP socket:
int s;
s = socket(AF_INET, SOCK_STREAM, 0);
There are two common ways to send discrete chunks of data across the 
wire.  You can either use UDP and send a discrete chunk as a datagram, 
or you can but structs into TCP data, and let them go as a stream.  
Using TCP is generally simpler and less failure-prone.  If you use UDP, 
just time out and keep requesting the same data until you get it.



Steps:

 (1).1st terminal
gcc  -o server_test server_test.c errlib.c sockwrap.c
 ./server_test -a 1500
2nd
telnet 127.0.0.1 1500

result
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is ‘^]‘.
2 7
9
close connection;
CTRL + ALT GR +  ] then Q


gcc  -g -o server_test server_test.c errlib.c sockwrap.c//needs to compile all c files used
valgrined ./server_test 127.0.0.1 1500
valgrindThe Valgrind tool suite provides a number of debugging and profiling tools that help you make your programs faster and more correct. The most popular of these tools is called Memcheck.  It can detect many memory-related errors that are common in C and C++ programs and that can lead to crashes and unpredictable behaviour.

The rest of this guide gives the minimum information you need to start detecting memory errors in your program with Memcheck.  For full documentation of Memcheck and the other tools, please read the User Manual. Preparing your program:

Compile your program with -g to include debugging information so that Memcheck‘s error messages include exact line numbers.  Using -O0 is also a good idea, if you can tolerate the slowdown.  With-O1 line numbers in error messages can be inaccurate, although generally speaking running Memcheck on code compiled at -O1 works fairly well, and the speed improvement compared to running -O0 is quite significant. Use of-O2 and above is not recommended as Memcheck occasionally reports uninitialised-value errors which don‘t really exist.http://valgrind.org/docs/manual/quick-start.html

)
no leakage:
==3112== All heap blocks were freed -- no leaks are possible

Use the functions Socket() and Connect() after having parsed the port number and the address
through the Getaddrinfo() function or, as alternatives, inet_addr() or inet_aton() functions. These
two alternatives, however, are not suggested as they are not portable to IPv6.

information of Getaddrinfo():

http://linux.die.net/man/3/getaddrinfo

(2)(3)

write client which needs to use another termial tap,and opens wireshark before running server.

(4)

use udp which for server,doesn‘t need to use listen(),accept(),close();for client,doesn‘t need to use connect().

1.whether client needs to bind or not?

On the client side, you would only use bind if you want to use a specific client-side port, which is rare. Usually on the client, you specify the IP address and port of the server machine, and the OS will pick which port you will use. Generally you don‘t care, but in some cases, there may be a firewall on the client that only allows outgoing connections on certain port. In that case, you will need to bind to a specific port before the connection attempt will work.

2.select()

select() and pselect() allow a program to monitor multiple file descriptors, waiting until one or more of the file descriptors become "ready" for some class of I/O operation (e.g., input possible).  A file descriptor is considered ready if it is possible to perform a corresponding I/O operation (e.g., read(2) without blocking, or a sufficiently small write(2)). select() can monitor only file descriptors numbers that are less than FD_SETSIZE; poll(2) does not have this limitation.

3.SCNu16

If I wanted to use for, for instance, scanf() to convert a string into a standard integer type, like uint16_t, I’d use SCNu16 from <inttypes.h>, like this:

#include <stdio.h>
#include <inttypes.h>
uint16_t x;
char *xs = "17";
sscanf(xs, "%" SCNu16, &x);

sscanf(buf,"%hu %hu",&op1,&op2);

printf( "%hu" ,  ‐1 );
"%hu" is an unsigned short int which is 16 bit.
-1 is "all-once", e.g. 0xffff.ffff, but since it gets converted to short it is only 0xffff. Which is 65535 as unsigned.

4.address

If it says 0.0.0.0 on the Local Address column, it means that port is listening on all ‘network interfaces‘ (i.e. your computer, your modem(s) and your network card(s))

why is loopback IP address from 127.0.0.1 to 127.255.255.254?

127.0.0.1 is the loopback Internet protocol (IP) address also referred to as the “localhost.” The address is used to establish an IP connection to the same machine or computer being used by the end-user. The same convention is defined for computer’s that support IPv6 addressing using the connotation of ::1. Establishing a connection using the address 127.0.0.1 is the most common practice; however, using any IP address in the range of 127.*.*.* will function in the same or similar manner. The loopback construct gives a computer or device capable of networking the capability to validate or establish the IP stack on the machine.


The 127/8 network can be used for a number of things.

1) Simulating a large number of different computers in a fast network (simply bring up more interfaces and bind services to them) without using virtual machines.  This might be helpful if you wanted to have a number of different web servers running locally on port 80 for some reason.

2) Permitting more locally running services than the 64k TCP would permit (though it seems unlikely that you would hit that limit rationally)

3) Playing games with people who aren‘t familiar with this factoid; "Hey, you‘re a loser hacker, I bet you can‘t even hack me.  Go ahead and try; I‘m at 127.45.209.66"

Probably other things too.

5.array and string

http://www.thegeekstuff.com/2011/12/c-arrays/

char buf[BUFLEN];
buf=argv[3];
error: assignment to expression with array type
 The error message is telling you that you can‘t assign to an array. For example,

char foo[4];
foo = "bar";        // This is an error
strcpy(foo, "bar"); // This is fine and dandy, like sour candy...

A "string" in C is a data layout, not a data type; it‘s defined as "a contiguous sequence of characters terminated by and including the first null character". An array of char may or may not contain a string, and the compiler isn‘t going to assume that it will hold a string. String literals are (almost always) null-terminated; character arrays are not


Note that the same happens if you tell the compiler that you have an array of the right size

void load_buffer(char buffer[100]) {
    /* prints 4 too! */
    printf("sizeof(buffer): %d\n", sizeof(buffer));
}

An array as parameter is just declaring a pointer. The compiler automatically changes that to char *name even if it was declared as char name[N].

If you want to force callers to pass an array of size 100 only, you can accept the address of the array (and the type of that) instead:

void load_buffer(char (*buffer)[100]) {
    /* prints 100 */
    printf("sizeof(buffer): %d\n", sizeof(*buffer));
}

It‘s a pointer to the array you have in main, so you need to dereference in the function to get the array. Indexing then is done by

buffer[0][N] or (*buffer)[N]

Nobody I know is doing that and I‘m neither doing it myself, because it rather complicates passing of the argument. But it‘s good to know about it. You can call the function like this then

load_buffer(&buffer)

If you want to accept other sizes too, i would go with the passing-N option the other two answers recommend.

So can use strlen which is easier:

strlen scans for the first ‘\0‘ null character. Since the contents of test_string are garbage, the behavior is undefined. It might return a small value if there happens to be a null character, or a large value or program crash if there don‘t happen to be any zero bytes

6.AF and PF

AF_* stands for Address Family
PF_* stands for Protocol Family

BSD man page promises:
"The protocol family generally is the same as the address family", and subsequent standards use AF_* everywhere.

Even linux/socket.h specifies as

#define PF_INET AF_INET

Yet, we can say

int socket(int family,int type,int prototype);

Here,family identifies family by address or protocol.Address family identifies a collection of protocol with the SAME ADDRESS FORMAT,while protocol family identifies a collection of protocol having SAME ARCHITECTURE.

7.ssize_t
    This data type is used to represent the sizes of blocks that can be read or written in a single operation. It is similar to size_t, but must be a signed type.
8.read() and write()

read()

    #include  <fcntl.h>
    int  read(  int  handle,  void  *buffer,  int  nbyte );

The read() function attempts to read nbytes from the file associated with handle, and places the characters read into buffer. If the file is opened using O_TEXT, it removes carriage returns and detects the end of the file.

The function returns the number of bytes read. On end-of-file, 0 is returned, on error it returns -1, setting errno to indicate the type of error that occurred.

write()

    #include  <fcntl.h>
    int  write(  int  handle,  void  *buffer,  int  nbyte  );

The write() function attempts to write nbytes from buffer to the file associated with handle. On text files, it expands each LF to a CR/LF.

The function returns the number of bytes written to the file. A return value of -1 indicates an error, with errno set appropriately.

9.\n \r

A line feed means moving one line forward. The code is \n. A carriage return means moving the cursor to the beginning of the line. The code is \r

sprintf(strings,"%s\r\n",ptr);//can append \r\n to string


receive data from client till receive ‘\n‘

ssize_t readline_unbuffered (int fd, void *vptr, size_t maxlen)
{
    int n, rc;
    char c, *ptr;
 
    ptr = vptr;
    for (n=1; n<maxlen; n++)
    {
        if ( (rc = recv(fd,&c,1,0)) == 1)
        {
            *ptr++ = c;
            if (c == ‘\n‘)
                break;    /* newline is stored, like fgets() */
        }
        else if (rc == 0)
        {
            if (n == 1)
                return 0; /* EOF, no data read */
            else
                break; /* EOF, some data was read */
        }
        else
            return -1; /* error, errno set by read() */
    }
    *ptr = 0; /* null terminate like fgets() */
    return n;
}


10.memset

void *memset(void *str, int c, size_t n) copies the character c (an unsigned char) to the first n characters of the string pointed to, by the argument str.

11.format

scanf("%c",&ptr[1]);can‘t use c,cz it will read only one character
//scanf("%s",ptr[1]);warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat],cz this may regard it as an offset,which is recognized as int
/*scanf("%s",&ptr[2]);//use "%s",the compiler automatically transfer it into ASCII from decimal
scanf("%s",&ptr[3]);
scanf("%s",&ptr[4]);*///can‘t use this cz if write 111 to ptr[2],will fill in ptr[2],ptr[3],ptr[4]

12.to install wireshark

for unknown reason,can‘t install directly from software center and terminal,then follow instructions to install from source online still have many errors then check online using like --with --without,but finally after "make" step,still can‘t run "make install"

successfully,but then found can install from software center and terminal....


以上是关于distributed programming---lab1(basic communication of server and client)的主要内容,如果未能解决你的问题,请参考以下文章

《Distributed Programming With Ruby》读书笔记一Drb:Hellowold and Pass by Reference

[Dwango Programming Contest 6th C] Cookie Distribution

cannot be run because the program file for 00100003 cannot be located on a distribution point

[Python] 安装pyperclip报错: No matching distribution found for pyperclip

七spark核心数据集RDD

原创大数据基础之SparkRDD原理及代码解析