Network Program Design Sockets

zhaozj2021-02-16  63

About Socket programming, there is a simple introduction in "Linux from the entry to the proficiency", more detailed can be referred to

"UNIX Network Programming Volume 1: Networking API: Sockets and XTI 2nd Edition" Tsinghua Photocopy Edition, which also said

Thread programming. A very good reference book, but no one translates it.

Hu Shushu translated a piece

"Network Programming", I collected it.

Please refer to Mr. Hu if there is an update.

Homepage.

___________________________________________________________________________________________________________________________________ | | 2, in any case, the author and the translator's name cannot be deleted. | 3, in any case, this article cannot enter the business area.

| | | | Hushu Yu | | (husuyu@linux.cqi.com.cn) | | | | November 1998 | | ______________________________________________________________________________ | Chapter 59 directory network programming port (Ports) and socket (Sockets) socket The word design socket () system call bind () system call listen () system call accept () system call setsockopt and GetSockOpt system call Connect () System call list 59.1 Server Side facing socket (Socket-Oriented) protocol program list 59.2 Client Side Function No connection (ConnectionLESS) Sockets Sockets Design program list 59.3 Server Note Record (RECORD) and file lock (Locking) process communication Skinth -------------------------------------------------- --------------------------- - Chapter 59 - Network Program Author Kamran Husain, Tim Parker Translator Hu Shuyu This chapter is port and Sockets Sockets Document Design Records and File Lock Processes Communication Reading This chapter requires that you have the following online programming basic concept ports and socket records and file lock proximeters communication. This article cannot be in a few pages. You said the entire content of the web program design. In fact, a first volume has a reference book to describe the network program design of 800 pages. If you want to make a network programming, you need a compiler. , TCP / IP and network operating systems have a lot of experience. In addition, you still need to have great patience. For details of TCP / IP, please see Tim Parker << Self-study TCP / IP 14 days >>

(SAMS Publish- ing). The port and socket network program design rely on socket acceptance and sending information. Although the word text seems to be a little mystery, but in fact, this concept is very easy to understand. Most web applications Use two protocols: Transfer Control Protocol (TCP) and User Packet Protocol (UDP). They use a port number to identify applications. The port number is used by the program running on the host, so that you can pass the number like a name. To track each application. The port number makes the operating system easier to know how many applications are using the system, and which services are valid. Theoretically, port numbers can be assigned by administrators on each host. But for more Good communication usually adopts some agreed agreements. These protocols enable the type of service requested to another system through the port number. Based on such a reason, most systems maintain a port number and what services they offer Document. The port number is assigned from 1. Typically port number exceeding 255 is reserved by the local host as a private use. 1 to 255 The number between the remote applications is used for the process and network services requested by the remote application. Each network communication Recycled the TCP application layer of the main computer. It is uniquely identified by two connected numbers. These two numbers set up a socket. The two numbers of forming sockets are the IP address and TCP software of the machine. The port number used. Because network communication includes at least two machines, there is a socket on the machine sent and received. Since each machine's IP address is unique, the port number is also unique in each machine. So, the socket should be unique in the network. Such settings can make the two applications in the network based on sockets based on sockets. Send and receive machine maintained a port table, which lists all Activated port number. Both machines include a process called binding, this is the entrance to each task, but it is just the opposite of the two machines. In other words, if the source port number of a machine is 23 and the destination port The number is set to 25, then the source port number of another machine is set to 25 destination port numbers to be set to 23. Skills Design Linux Support Berkeley (BSD)-style socket programming. It supports connection and not Connect type socket. On the connection-oriented communication, the server and client will build a connection before switching the data. No connection between the data is exchanged as part of the information. No matter that way, the server is always the most Start first, bind your own bindings on a socket, then listen to the information. How do the server try to listen to the type of connection you programmed. You need to know some system calls Socket () bind () listen () accept () setsockopt () and getsockopt () Connect () Sendto () Recvfrom () We will use these system calls in the following examples. Socket () system calls socket () system call to create a socket to the client or server, the socket function is defined below: #include #include int socket (int name, int type, int protocol) family = af_UNIX.TYPE in Linux can be SOCK_STREAM It is reliable although communication speed is slow It can also be SOCK_DGRAM it is fast but unreliable. If type = sock_stream is then protocol = ipproto_ tcp. If Type = SOCK_DGRAM is then protocol = ipproto_udp. If an error, the function will return -1. Otherwise returns a socket descriptor You can use this socket with the socket descriptor in the call behind the program. There is no name when the socket is created. The client is read to write it with the name of the socket. This is the following binding function to do. Things. Bind () system calls bind () system call to allocate a name without the name. The binding function is defined: #include #include

INT Bind (int SockFD, Struct SockAddr * Saddr, int Addrlen) The first parameter is a socket descriptor. The second parameter is a structure used by the name. The third parameter is the size of the structure. Now you are already Your client or server limits an address, you can talk to the server or listen on the server. If your program is a server, then set it yourself to listen, then wait for the connection. Let us look See which functions can make you try to do this. Listen () system calls listen () system calls are used by the server. There is a definition below: #include #include int.H> int> Int Listen (int suckfd, int backlog); SockFD is a socket descriptor. The backlog is a number that has not been decided in a time that is not decided to reject. Generally, the standard value 5. If an error occurs, the return value is less than 1. If this The call is successful, you can already be accepted. Accept () system call accept () call is used by the server to accept any information introduced from the client connect () call. Must be understood, if not accepting this function No value will not return. It is like this: #include #include int access (int Sockfd, struct socmedr * peeraddr, int addrlen) In addition to PEERADDR Outside the request, other parameters and bind () system calls are the same. On the basis of information introduction, the domains of the structure points to the peeraddr are filled with respective values. SetsockOpt () and getSockopt () system call Linux The Socket library provided contains an error (bug). This error manifests you cannot re-enable the same port number for a socket, even after you get the socket. For example, if you say, you write a server. In a socket, wait for a program. The server opens the socket and listens on it is no problem. In any case, there are always some reasons (whether it is normal or abnormal end procedures) makes your program need to be re- Start. However, you can't bind it to the original port after restarting. The error code returned from a bind () system call always reports that the port you try to connect has been bound by other processes. The problem is The Linux kernel never marks the port after the process of binding sockets. Most most In the number of UN IX systems, the port can be repeatedly used by a process, and can even be used by other processes. Wrap the problem in Linux is that the socket has been opened but not connected, and the setsockopt () system is called. To set the option (options) .SetSockOpt () call setting options to get options from a given socket. This is the syntax of these calls: #include #include

INT GetSockopt (int sockfd, int tent, int name, char * value, int * optlen) int setsockopt (int Sockfd, int level, int name, char * value, int * optlen) SOCKFD must be an open socket .level is the protocol standard (T CP / IP protocol) (TE CP / IP protocol uses IPPROTO_TCP, the SLR standard options utility SOL_SOCKET), the name of the option (Name) is in detail in the socket manual (Man Page) Description. * Value points to the value of the value set to the getSockOpt () function or the setsocko pt () function set .optlen pointer points to an integer, the integer contains the length of the parameter to byte. The value is obtained by getSockOpt () Setting and its value must be set by the programmer when using a second section of the SetSockOpt (SetsockOpt (2)) in the User Manual. Now let's go back to Linux. When you open a socket, you must call the setSockopt () function at the same time: #ifdef Linux Opt = 1; LEN = SizeOf (OPT); Setsockopt (SockFD, SOL_Socket, So_reuseAddr, & Opt, & Len); # Endif Only when you want to make the program not only in the Linux system, # ifdef and #endif description is required. Some U NIX systems may not support or do not need a SO_REUSEADDR flag. Connect () system calls connection CONNECT () call Use the client connection server in the connection-oriented system. The call must be used after bind (). It is defined: #include #include int Connect (int SockFD, Struct SockAddr * Servs Addr, int Addrlen) In addition to servsaddr, all parameters are the same as BIND calls, ServsAddr points to the information of the server connected to the client. When the request is received, the Accept call is created to the server. A new socket. Then the server can be fork () The new process is then waiting for other connections. On the server side you can write code program list 59.1 Satisfaction Listing 59.1 Slide-to-Tag Protocol, Listing Protocol, Launcher 59.1. .h> #include #include #define my_port 6545 main (int Argc, char * argv []) {Int Sockfd, newfd; int cpid; / * child id * / struct sockaddr_in servaddr; struct sockaddr_in clientInfo; if ((sockfd = socket (AF_INET, SOCK_STREAM, 0) <0) {myabort ( "Unable to create socket");} #ifdef LINUX opt = 1; len = sizeof (opt) ; setsockopt (sockfd, SOL_SOCKET, SO_REUSEADDR, & opt, & len); #endif bzero ((char *) & servaddr, sizeof (servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl (INADDR_ANY); servaddr.sin_family =

HTONS (my_port); / * * The HTONL (for a long "and htons (for short integer) Convert * a host oriented byte Order * INTO a network order. * / if (bind (Sockfd, (Struct SockAddr *) & Servaddr SIZEOF (STRUCKADDR) <0) {Myabort ("Unable to Bind Socket");} listen (SockFD, 5); for (;;) {/ * Wait here * / newfd = accept (Sockfd, (Struct SockAddr) *) & clientInfo, SIZEOF (STRUCT SOCKADDR); if ("Unable to Accept on Socket");} IF ((CPID = fork ()) <0) {Myabort ("Unable to fork on accept ");} else if (cpid == 0) {/ * child * / close (sockfd); / * no need for original * / do_your_thing (newfd); exit (0);} close (newfd); / * in In the program-oriented protocol, the server performs the following function: call the socket () function Create a socket. Call the bind () function Bind yourself to call the listen () function listen Connection call accept () function Accept all the introduced request calls the read () function getting the introduced information and then calls Write () to answer us to see what the client wants to do, see the program list 59.2. Program List 59.2 Client functions #include #include #include #include #define my_port 6545 #define my_host_addr "204.25.13.1" int GetServersocketID () {INT FD, LEN; STRUCT SOCKADDR_IN UNIX_ADDR; / * CREATE A UNIX DOMAIN STREAM Socket * / IF ((fd = socket (AF_UNIX, SOCK_STREAM, 0)) <0) {Return (-1);} #ifdef Linux opt = 1; len = sizeof (opt); setsockopt (sockfd, SOL_SOCKET, SO_REUSEADDR, & opt, & len); #endif / * fill socket address structurew / our address * / memset (& unix_addr, 0, sizeof (unix_addr)); unix_addr .sin_family = AF_INET; / * convert internet address to binary value * / unix_addr.sin_addr.s_addr = inet_addr (MY_HOST_ADDR); unix_addr.sin_family = htons (MY_PORT); if (bind (fd, (struct sockaddr *) & unix_addr, len) <0) RETURN (-2); MEMSET (&)

UNIX_ADDR, 0, SIZEOF (UNIX_ADDR)); IF (Connect (FD, (Struct SockAddr *) & Unix_addr, len) <0) Return (-3); Return (FD);} In-connection-oriented communication clients to do Some things: Call the socket () function Create a socket call CONNECT () function Attempts to connect the server if the connection successfully calls the Write () function request data, call the read () function Receive the incoming response to the ConnectionLESS socket Programming Now let us consider unconnected information exchange. The principle of the server side and the connection-oriented protocol are different. The server does not call the Listen and Accept but call RecVFrom (). Similarly, the server uses the sendto () function Answer information. Server-side program See program list 59.3. Program list 59.3 Server side #include #include #include #include #define MY_PORT 6545 #define MAXM 4096 char mesg [MAXM]; main (int argc, char * argv []) {int sockfd, newfd; int cpid; / * child id * / struct sockaddr_in servaddr; struct sockaddr_in clientInfo; IF ((Sockfd = Socket (AF_INET, SOCK_STREAM, 0) <0) {Myabort ("Unable to create socket");} #ifdef linux opt = 1; len = sizeof (opt); setsockopt (sockfd, sol_socket, so_reuseaddr, & opt, & len; #ndif Bzero ((char *) & servaddr, SIZEOF (SERVADDR)); servaddr.sin_family = AF_INET; Servaddr.sin_addr.s_addr = HTONL (INADDR_ANY); servaddr.sin_family = HTO NS (my_port); / * * The HTONL (for a long) and htons (for short integer) Convert * A host oriented byte Order * INTO a network order. * / if (bind (Sockfd, (Struct SockAddr *) & Servaddr SIZEOF (STRUCKADDR) <0) {Myabort ("Unable to Bind Socket");} for (;;) {/ * Wait Here * / N = Recvfrom (SockFD, Mesg, Maxm, 0, (Struct SockAddr * ) & clientInfo, Struct SockAddr); DOSMETHINGTOIT (MESG); Sendto (SockFD, Mesg, N, 0, (Struct Sockaddr *) & ClientInfo, Sizeof (Struct SockAddr);

}} Have you seen it, handle each message only calls two functions, which is easier than the connection-oriented protocol. But you must, no matter how, you have to handle each message at the same time, because the message from multiple clients The server is turning. In the connection-oriented protocol, the child process always knows where each message is. The client can also call the connection () system call. But the client can call the sendto () function directly. Client Elephant and The server is roughly the same. Just call sendto () before calling Recvfrom (): #include #include int sendto ((int sockfd, const void * message__, / * THE POINTER TO Message * / Int Length, / * of message * / unsigned int type, / * of ruting, leave 0 * / const structure sockaddr * client, / * where to send it * / int ingth); / * of sockaddr * / Note: If you are using the BSD system, use the Sendto () system call, do not use sendmsg () because send to () performance is better. If an error returns -1, but only local errors can be checked. Recvfrom () system call is defined: #include #include int cablefrom (int sockfd, const void * message__, / * the pointer to message * / int LENGTH, / * of message * / unsigned int flag, / * of routing, leave 0 * / const struct sockaddr * client, / * where to send it * / int length); / * of sockaddr * / If one information big buffer Can't let go, then the additional information will be cut off. This call can return immediately, or wait for a long time. This depends on what type you set to Flags. You can even set up timeout. In the Manual (Man Pages) More information of Recvfrom can be found. You have Learn how to use Linux's performance, the basic knowledge of network applications. We don't intend to further describe more complex network programming. An excellent starting point for more details information is reference W. Ric Hard Stevens << UNIX network program design >> (Prentice Hall, 1990). This book is a classic textbook used by many universities. The content is extremely detailed. Record and file lock When two processes share a file, there is a piece Very dangerous thing. If a process changed the file directory, then there must be an effect to another process. Based on this reason, most operating systems use a mutual exclusive principle: When a process has a file, other processes You can't touch this file again. This is called file lock. This technology is very easy to implement. Usually what happens is that the so-called "locked file"

Just create a file with the same name with the source file and plus the .lock extension. This tells other processes that this file can no longer touch the .Linux spool printing system and uuCP is to lock it. This may be a kind The rude method, but it is very simple to program. Unfortunately, when you have several processes to process the same information at the same time, this technology is not practical. Because the latency will be turned on and off will It has become very long. The same process is not able to release files correctly, and other processes will hang there, waiting for access to access. For this reason, the record lock is usually used. Locked with records, a small file Part is locked to prevent two processes from changing it at the same time. If necessary, record locks can allow multiple processes to simultaneously access different partial records of the same file. Of course, the record lock programming is more complicated than implementing files. Usually, Implementing the record lock You need to use the file offset or the number of characters to the beginning of the file. In most programs, the characters within a range are locked. The program records the start and length of the lock range, and saves Other processes can be queried. Whether writing file locks or record locks requires good understanding of the operating system. But it is not difficult. In particular, it is easy to get from the Internet, Network Program Guide and BBS. Thousands of procedures. You can view the source code for these programs. The inter-process communication network programming typically includes two or more processes will be interprocess Communications. Therefore, the process of process communication is extremely extreme in network programming. Important. Network programming is different from general aspects from general programming methods. A traditional program can be dialogue through global variables or function calls and different modules (even other applications on the same machine). But It is not in the network. An important goal of the network program design is to ensure that the process does not interfere. Otherwise, the system may be suspended or self-locking. Therefore, the process must communicate with a concise and effective way. In this regard, UNIX It has very significant robustness. Because many of UNIX's basic properties such as pipelines, queues are very suitable for the network. Compared to single application code, the code between the process is more complicated. If you want to write such a program, you can Learn the online program design guide and the example program on the BBS site. To understand these tasks, it is done. Summary rarely want to write a web application, so the details of the process are best left to those who want to write. Practice and consultation A large number of examples are the best way to start writing network code. But you have to spend many years. ---------------------- --------- English original ------------------------- ------- - 59 - Network Programming Ports and Sockets Socket Programming The socket () System Call The bind () System Call The listen () System Call The accept () System Call The setsockopt () and getsockopt () System .. Calls The connect () System Call Listing 59.1 The server side for a socket-oriented protocol Listing 59.2 The client side function Connectionless socket Programming Listing 59.3 The server side NOTE Record and File Locking Interprocess Communications Summary -.... 59 - Network Programming by Kamran Husain and Tim Parker IN THIS CHAPTER Ports and Sockets Socket Programming Record and File Locking Interprocess Communications This chapter looks at the basic concepts you need for network programming:

Ports and sockets Record and file locking Interprocess communications It is impossible to tell you how to program applications for a network in just a few pages. Indeed, the best available reference to network programming takes almost 800 pages in the first volume alone!

If you really want to do network programming, you need a lot of experience with compilers, TCP / IP, and network operating systems - and you need a great deal of patience For details on TCP / IP, check the book Teach Yourself TCP. / IP in 14 Days, by Tim Parker (Sams Publishing). Ports and Sockets Network programming relies on the use of sockets to accept and transmit information. Although there is a lot of mystique about sockets, the concept is actually simple to understand. Most applications that use the two primary network protocols, Transmission Control Protocol (TCP) and User Datagram Protocol (UDP) have a port number that identifies the application. A port number is used for each different application the machine is handling, so it can keep track of those applications by numbers rather than names. The port number makes it easier for the operating system to know how many applications are using the system and which services are available. In theory, port numbers can be assigned on individ ual machines by the system administrator, but some conventions have been adopted to allow better communications. These conventions enable the port number to identify the type of service that one system is requesting from another. For this reason, most systems maintain a file of port numbers and their corresponding services. Port numbers are assigned starting from the number 1. Normally, port numbers above 255 are reserved for the private use of the local machine, but numbers between 1 and 255 are used for processes requested by remote applications or for networking services Each Network Communications Circuit Into and Out of The Host Computer '

s TCP application layer is uniquely identified by a combination of two numbers, together called the socket. The socket is composed of the IP address of the machine and the port number used by the TCP software. Because at least two machines are involved in network communications , there will be a socket on both the sending and the receiving machine. Because the IP address of each machine is unique and the port numbers are unique to each machine, socket numbers are also unique across the network. This setup enables an application to talk to another application across the network based entirely on the socket number. The sending and receiving machines maintain a port table that lists all active port numbers. The two machines involved have reversed entries for each session between the two, a process called binding. In other Words, if One Machine Has The Source Port Number 23 and The Destination Port Number Set At 25, The Other Machine Has ITS Source Port Number Set At 25 and The Destination port number set at 23. Socket Programming Linux supports BSD-style socket programming. Both connection-oriented and connectionless types of sockets are supported. In connection-oriented communication, the server and client establish a connection before any data is exchanged. In connectionless communication , data is exchanged as part of a message. In either case, the server always starts first, binds itself to a socket, and listens to messages. How the server attempts to listen depends on the type of connection for which you have programmed it. You NEED TO KNOW ABOUT A FEW SYSTEM CALLS:

socket () bind () listen () accept () setsockopt () and getsockopt () connect () sendto () recvfrom () We will cover these system calls in the following examples. The socket () System Call The socket () system Call Creates A Socket for the Client or the Server. The socket function is defined as shown here: #include #include int socket (int name, int type, int protocol) for Linux, you will have family = AF_UNIX. The type is either SOCK_STREAM for reliable, though slower, communications or SOCK_DGRAM for faster, but less reliable, communications. The protocol should be IPPROTO_TCP for SOCK_STREAM and IPPROTO_UDP for SOCK_DGRAM. The return value from this function is -1 if there was an error;.. otherwise, it's a socket descriptor You will use this socket descriptor to refer to this socket in all subsequent calls in your program Sockets are created without a name Clients use the name of the socket. To Read or Write to It. this is where the bind function comes in. The bind ) System call assigns a name to an unnamed socket. The bind function is defined like this: #include #include int bind (int sockfd, struct) sockaddr * saddr, int addrlen) The first item is a socket descriptor. The second is a structure with the name to use, and the third item is the size of the structure. Now that you have bound an address for your server or client, You can connect () To it or listen on it. if you ram is a server, it sets itself up to listen and accept connects. let '

Siok at the function available for such an endeavor. The listen () system call the listen () system call is buy by the server. it is defined in the folding Way: #include #include int listen (int sockfd, int backlog); The sockfd is the descriptor of the socket The backlog is the number of connections that are pending at one time before any are rejected Use the standard value of 5 for backlog.. . A returned value of less than 1 indicates an error. If this call is successful, you can accept connections. The accept () System Call The accept () system call is used by a server to accept any incoming messages from clients' connect ( ) Calls. Be aware tris function does not returnix if no connections are received. it is defined Like this: #include #include

int accept (int sockfd, struct sockaddr * peeraddr, int addrlen) The parameters are the same as those for the bind call, with the exception that the peeraddr points to information about the client that is making a connection request. Based on the incoming message , the fields in the structure pointed at by peeraddr are filled out. The setsockopt () and getsockopt () System Calls The socket libraries provided with Linux include a bug. The symptom of this bug is that you can not reuse a port number for a socket even if you closed the socket properly. for example, say you write your own server that waits on a socket. This server opens the socket and listens on it with no problems. However, for some reason (a crash or normal termination), when the program is restarted, you are not able to bind to the same port. The error codes from the bind () call will always return an error indicating that the port you are attempting to connect to is already bound to another process. The problem is That the lin ux kernel never marks the port as unused when the process bound to a socket terminates. In most other UNIX systems, the port can be used again by another invocation of the same or even another process. The way to get around this problem in Linux is to use the setsockopt () system call to set the options on a socket when it is opened and before a connection is made on it. The setsockopt () sets options and the getsockopt () call gets options for a given socket. Here is the Syntax for these calls: #include #include

int getsockopt (int sockfd, int level, int name, char * value, int * optlen) int setsockopt (int sockfd, int level, int name, char * value, int * optlen) The sockfd must be an open socket. The level is the protocol level to use for the function (IPPROTO_TCP for TCP / IP and SOL_SOCKET for socket level options), and the name of the option is as defined in the socket's man page. The * value pointer points to a location where a value is stored for getsockopt () or when a value is read for setsockopt () The optlen parameter is a pointer to an integer containing the length of the parameters in bytes;. the value is set by getsockopt () and must be set by the programmer when making a call via setsockopt (). The full man page with details of all the options is found in the man page setsockopt (2). Now back to the bug in Linux. When you open a socket, you must also call the setsockopt ( ) function with the folloading segment of code: #ifdef linux opt = 1; len = sizeof (opt); setsockopt (sockfd, sol_socket, so_reuse ADDR, & opt, & len); #endif The #ifdef and #endif statements are necessary only if you want to port the code over to systems other than Linux Some UNIX systems might not support or require the SO_REUSEADDR flag The connect () System.. Call The connect () system call is used by clients to connect to a server in a connection-oriented system This connect () call should be made after the bind () call It is defined like this:.. #include #include

int connect (int sockfd, struct sockaddr * servsaddr, int addrlen) The parameters are the same as those for the bind call, with the exception that the servsaddr points to information about the server that the client is connecting to. The accept call creates a new socket for the server to work with the request. This way, the server can fork () off a new process and wait for more connections. On the server side of things, you would have code that looks like that shown in Listing 59.1. Listing 59.1. The Server Side for a socket-Oriented Protocol. #Include #include #include #include # define MY_PORT 6545 main (int argc, char * argv []) {int sockfd, newfd; int cpid; / * child id * / struct sockaddr_in servaddr; struct sockaddr_in clientInfo; if ((sockfd = socket (AF_INET, SOCK_STREAM, 0) <0) {Myabort ("Unable to create socket");} #ifdef Linux opt = 1; len = sizeof (opt); setsockopt (SockFD, SOL_Socket, SO_REUSEADDR, & OPT, & LEN); #ENDIF BZERO ((charr) *) & Servaddr, sizeof (servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl (INADDR_ANY); servaddr.sin_family = htons (MY_PORT); / * * The htonl (for a long integer) and htons ( for short integer) convert * a host oriented byte order * into a network order. * / if (bind (sockfd, (struct sockaddr *) & servaddr, sizeof (struct sockaddr)) <0) {myabort ( "Unable to bind socket" } listen (SOCKFD, 5); for (;;) {/ * Wait here * / newfd = accept (SockFD, (Struct SockAddr *) & ClientInfo, SIZEOF (Struct SockAddr); if (newfd <0) {Myabort "Unable to accept on socket");} IF ((CPID = fork ()) <0) {Myabort ("

Unable to fork on accept ");} else if (cpid == 0) {/ * child * / close (sockfd); / * no need for original * / do_your_thing (newfd); exit (0);} close (newfd ); / * in the parent * /}} in the case of connection-oriented protocols, the server performs the following functions: Creates a socket with a call to the socket () function Binds itself to an address with the bind () function call Listens for connections with the listen () function call Accepts any incoming requests with the accept () function call Gets incoming messages with the read () function and replies with the write () call Now let's look at the client side of things, in Listing 59.2. The client side function. #Include #include #include #include #define my_port 6545 #define MY_HOST_ADDR "204.25.13.1" int getServerSocketId () {int fd, len; struct sockaddr_in unix_addr; / * create a Unix domain stream socket * / if ((fd = socket (AF_UNIX, SOCK_STREAM, 0)) <0) {RETURN (-1) ;} #Ifdef LINUX opt = 1; len = sizeof (opt); setsockopt (sockfd, SOL_SOCKET, SO_REUSEADDR, & opt, & len); #endif / * fill socket address structure w / our address * / memset (& unix_addr, 0, sizeof (unix_addr)); unix_addr.sin_family = AF_INET; / * convert internet address to binary value * / unix_addr.sin_addr.s_addr = inet_addr (MY_HOST_ADDR); unix_addr.sin_family = htons (MY_PORT); if (bind (fd, (struct sockaddr *) & unix_addr, len) <0) Return (-2); MEMSET (& UNIX_ADDR, 0, SIZEOF (UNIX_ADDR)); IF (Connect (FD, (Struct SockAddr *) & Unix_addr, len) <0) Return (-3) Return (FD);

} The client for connection-oriented communication also takes the following steps: Creates a socket with a call to the socket () function Attempts to connect to the server with a connect () call If a connection is made, requests data with the write ( ) call, and reads incoming replies with the read () function Connectionless Socket Programming Now let's consider the case of a connectionless exchange of information. The principle on the server side is different from the connection-oriented server side in that the server calls recvfrom ( Rather Than The Listen and Accept Calls. Also, To Reply To Messages, The Server Uses The Sendto () Function Call. See Listing 59.3 for the Server Side. Listing 59.3. The Server Side. #include #include #include #include #define my_port 6545 #define maxm 4096 char MESG [MAXM]; Main (int Argc, char * argv [ ]) {INT SOCKFD, NewFD; INT CPID; / * Child ID * / Struct SockAddr_in Servaddr; Struct SockAddr_in ClientInfo ; if ((Sockfd = Socket (AF_INET, SOCK_STREAM, 0) <0) {Myabort ("Unable to create socket");} #ifdef linux opt = 1; len = sizeof (opt); setsockopt (SockFD, SOL_Socket, SO_REUSEADDR , & opt, & len); #endif bzero ((char *) & servaddr, sizeof (servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl (INADDR_ANY); servaddr.sin_family = htons (MY_PORT); / * * The htonl (for a long integer) and htons (for short integer) convert * a host oriented byte order * into a network order. * / if (bind (sockfd, (struct sockaddr *) & servaddr, sizeof (struct sockaddr)) <0) {Myabort ("Unable to Bind Socket");} for (;;) {/ * Wait Here * / n =

recvfrom (sockfd, mesg, MAXM, 0, (struct sockaddr *) & clientInfo, sizeof (struct sockaddr)); doSomethingToIt (mesg); sendto (sockfd, mesg, n, 0, (struct sockaddr *) & clientInfo, sizeof (struct sockaddr ));}} As you can see, the two function calls to process each message make this an easier implementation than a connection-oriented one you must, however, process each message one at a time because messages from multiple clients can be multiplexed. together. In a connection-oriented scheme, the child process always knows where each message originated. The client does not have to call the connect () system call either. Instead, the client can call the sendto () function directly. The client side Is Identical To The Server Side, With The Exception That The Sendto Call is Made Before The Recvfrom () Call: #include #include int sendto ((int Sockfd, Const Void) * Message__, / / ​​/ * the pointer to message * / int layth, / * of message * / unsigned int type, / * of routing, leave 0 * / const Struct Sockaddr * Client, / * Where to send it * / int length); / * of sockaddr * / Note: if you are a bsd user, use the sendto () call, not the sendmsg () call. The sendmsg () Call. The sendto () call is more efficient Any errors are indicated by a return value of -1 Only local errors are detected The recvfrom () system call is defined as shown here:... #include #include int recvfrom (int sockfd, const void * message__, / * the pointer to message * / int length, / * of message * / unsigned int flags, / * of routing, leave 0 * / const struct sockaddr * client, / * where to send it * / int layth);

/ * Of sockaddr * / If a message is too long to fit in the supplied buffer, the extra bytes are discarded. The call might return immediately or wait forever, depending on the type of the flag being set. You can even set timeout values .. Check the man pages for recvfrom for more information There you have it -. the very basics of how to program applications to take advantage of the networking capabilities under Linux We have not even scratched the surface of all the intricacies of programming for networks . A good starting point for more detailed information would be UNIX Network Programming, by W. Richard Stevens (Prentice Hall, 1990). This book, a classic, is used in most universities and is by far the most detailed book to date. Record and File Locking When two processes want to share a file, the danger exists that one process might affect the contents of the file, and thereby affect the other process For this reason, most operating systems use a mutually exclusive principle:. when one p rocess has a file open, no other process can touch it. This is called file locking. This technique is simple to implement. What usually happens is that a "lock file" is created with the same name as the original file but with the extension .lock, which tells other processes that the file is unavailable. This is how many Linux spoolers, such as the print system and UUCP, implement file locking. It is a brute-force method, perhaps, but effective and easy to program. Unfortunately , this technique is not good when you must have several processes access the same information quickly, because the delays waiting for file opening and closing can grow to be appreciable. Also, if one process doesn '

t release the file properly, other processes can hang there, waiting for access. For this reason, record locking is sometimes implemented. With record locking, a single part of a larger file is locked to prevent two processes from changing its contents at the same time. Record locking enables many processes to access the same file at the same time, each updating different records within the file, if necessary. The programming necessary to implement record locking is more complex than that for file locking, of course. Normally, to implement record locking, you use a file offset, or the number of characters from the beginning of the file In most cases, a range of characters is locked;. the program has to note the start of the locking region and the length of it, and then store that information where other processes can examine it. Writing either file-locking or record-locking code requires a good understanding of the operating system but is otherwise not difficult, especially because tho usands of programs are readily available from the Internet, in networking programming books, and on BBSs to examine for sample code. Interprocess Communications Network programming always involves two or more processes talking to each other (interprocess communications), so the way in which processes communicate is vitally important to network programmers. Network programming differs from the usual method of programming in a few important aspects. A traditional program can talk to different modules (or even other applications on the same machine) through global variables and function calls. That doesn ' T Work Across NetWorks. a Key Goal of Network Programming is to ensure That Processes Don '

转载请注明原文地址:https://www.9cbs.com/read-15600.html

New Post(0)