network programming

xiaoxiao2021-03-05  25

This chapter mainly introduces the basic knowledge of network programming. Since there are some simple source program instances in the back of the book to explain the basic concepts of each chapter, there must be necessary network programming knowledge. In the usual work, in order to find security vulnerabilities, you also need to write some short-fooled programs to replace complex manual command input. In the operating system chapter, C language programming and debugging in Linux has been introduced. On the basis of the first two chapters, first, Linux provides a good support for network communications. Since the Windows system is currently very popular, especially developing environment Visualc , this chapter also introduces the network programming in the Windows environment. The first section of Linux Network Programming (Berkeley Sockets) We can think that the socket is to extend the file operation of the UNIX system to provide a point-to-point communication. If you want to operate files, the application creates a socket according to the needs of the application. The operating system returns an integer. The application uses this socket by reference to this positive number. Different points of the file descriptor and socket descriptor are in that the program is called Open (), the operating system bries a file descriptor to a file or device, but when you create a socket, you can not Bind to a target address. The program can specify the target address when anyworthy wants to use this socket. In a communication program of point-to-point, we call the program of the request service or data called client programs, and software that provides data or service is called server programs. Figure 1 is a flow chart of a connected server program and a client program. For a server program and client program that uses connectionless protocols, see Figure 2. In the figure, the client program is not connected to the server program, which is sent to the server by using the server address as a Sendto () system call to the parameter. Similarly, the server does not accept the client's connection, but uses the RECVFROM () call the data waiting from the client. Socket System Call Next explanates a few basic socket system call functions. As long as you compare the following function to the system's input and output function call, you can quickly grasp these functions. Socket () ----------------------------------------------- ------------- # include #include int socket (int name, int type, int protocol); ------ -------------------------------------------------- ---- Int Family parameter Specifies the communication protocol to use, take the following values. Value AF_UNIX UNIX Internal Protocol AF_INET Internet Protocol AF_NS Xerox NS Protocol AF_IMPLINK IMP Connection Layer INT TYPE Specifies the type of socket, take the following value value enlightenment SOCK_STREAM Flow Tag SOCK_DGRAM Data Supply Set SOCK_RAW Roof Socket The SOCK_SEQPACKET sequential packaging INT protocol parameter is usually set to 0. Socket () system call returns an integer value called a socket descriptor word sockfd, which is the same as the file descriptor. The first step of network I / O is usually calling this function.

SOCEKTPAIR () ----------------------------------------------- ------------- # Include #include int socketpair (int name, int type, int protocol, int suckvec [2]); -------------------------------------------------- ---------- This call returns two socket descriptors, SockVec [0] and SockVec [1], they have no name, but connected. This call is similar to the pipeline system call. The structure created by this call is called a stream. Bind () ----------------------------------------------- ------------- # include #include int bind (int sockfd, struct socmeddr * myaddr, int address; ---- -------------------------------------------------- ------ This call named a name to a socket without a name. The second parameter MyAddr is a pointer to a particular protocol address, and the third parameter is the size of this address structure. Bind () has three functions: Server registers their address customers in the system to register an address for itself to make sure the system is fixed assigned to it a unique address () ---------------- -------------------------------------------------- #include #include int cablefd, struct sockaddr * servaddr, int addrlen; ----------------- ------------------------------------------ This process is in socket () call After, a socket descriptor and a connection to the connection established with the server are described. SockFD is a socket descriptor returned by socket () call. The second parameter is the pointer of the server socket address, and the third parameter is the length of this address. Listen () ----------------------------------------------- ------------- # include #include int Listen (int sockfd, int backlog) ---------- -------------------------------------------------- Connected server uses this system call to indicate that it wants to accept the connection. This system call usually calls before Socket () and bind (). Parameters Backlog means that the system can queue how many connection requests can be queued when they wait for an Accept () system call.

Accept () --------------------------------------------- ------------- # include #include int access (int sockfd, struct sockaddr * peer, int * addrlen); -------------------------------------------------- ------ On a servers that establish a good connection execute the Listen () system call, an actual and customer connection procedure waits for the server to call an Accept () system call. Accept () Remove the first connection request in the queue and create another and SOCKFD has the same properties. If there is no connection request in the queue, this call will block the caller and know that there is a request. The peer and addrlen parameters are used to return the address of the connected client. The caller sets the value of Addrlen before calling, and the system call returns a value. Send (), sendto (), recv (), recvfrom () ----------------------------------- ------------------------- # include #include int desund (int sockfd, char * Buff, int Nbytes, int 4; int SENDTO (int Sockfd, CHAR * BUFF, INT NBYTES, INT FLAGS, STRUCT SOCKADDR * TO, INT Addrlen); int cablefd, char * buff, int nbytes, int flags Int Recvfrom (int SockFD, Char * Buff, Int Nbytes, Int Flags, struct sockaddr * from, int addrlen); ----------------------- ------------------------------------- These calls and standard systems call read () and Write ( )similar. These calls require additional parameters. The Flag parameter can be 0 or the following constant: MSG_OOB accepts or sends a binding data MSG_PEEK surveillance into information MSG_DonTroute bypassing the routing () ------------------- --------------------------------------- # include #include int close (int suckfd); ------------------------------------ ------------------------ Close a socket.

Programming example read N-byte data from a descriptor read N-byte data from a descriptor * / int in (Register INT FD, Register Char * PTR, Register Int Nbytes) {Int NLIFT, NREAD; NLEFT = Nbytes; While (NLEFT> 0) {nread = read (FD, PTR, NLEFT); if (NREAD <0) Return (NREAD); Else IF (Nread == 0) Break; NLEFT- = NREAD; PTR = nread;} Return (NBYTES - NLEFT);} Write N-byte data to a descriptor / * write n-byte data to a descriptor * / int WRITEN (Register int FD, Register Char * PTR, Register Int nbytes) {Int NLEFT, NWRITTEN; NLIT = NBYTES; while (NLITTEN = Write (FD, PTR, NLEFT); if (nwritten <= 0) return (nLITTEN); NLITTEN); NLIFT - = NWRITTEN; PTR = nwritten;} return (Nbytes -nleft;} TCP program / * inet.h * server and client program's header file. * / # include #include #include #include #include #define serv_udp_port 6000 # Define serv_tcp_port 6000 # define serve_host_addr "192.43.235.6" / * host addr for server * / char * PNAME; server programs as follows: / * TCP server program * / # include "inet.h" main (int Argc, char * argv) {Int SockFD, Newsockfd, Clilen, ChildPid; Struct Sockaddr_in CLI_ADDR, Serv_addr; PNAME = Argv [0]; / * Open a TCP Socket (an Internet Flow Jacket) * / if ((SockFD = Socket (AF_INET, SOCK_STREAM, 0)) <0) Err_dump ("Server: CAN't Open Stream Socket"); / * Bind local address, so that the client can access the server. * / Bzero ((char *) & serv_addr, sizeof (serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl (INADDR_ANY); serv_addr.sin_port = htons (SERV_TCP_PORT); if (bind (sockfd, (struct SockAddr *) & serv_addr, sizeof (serv_addr)) <0) Err_dump ("Server: can't Bind Local Address); Listen (SOCKFD, 5); for (;;;;;) {/ * Waiting for a connection process from the client This is a concurrent server.

* / Clilen = sizeof (cli_addr); newsockfd = accept (sockfd, (struct sockaddr *) & cli_addr, & clilen); if (newsockfd <0) err_dump ( "server: accept error"); if ((childpid = fork ()) <0) Err_Dump ("Server: fork Error"); Else if (ChildPid == 0) {/ * child process * / close (sockfd); / * Close the original socket * / str_echo (newsockfd); / * Processing request * / exit (0);} close (newsockfd); / * Parent process * /}} server code: / * Using TCP protocol client * / # include "inet.h" main (argc, argv) int Argc; char * argv []; {Int Sockfd; struct sockaddr_in serv_addr; pname = argv [0]; / * Filling the address of the server you want to connect to the server in the structure "serv_addr" * / bzero ((char *) & serv_addr, sizeof (serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = inet_addr (SERV_HOST_ADDR); serv_addr.sin_port = htons (SERV_TCP_PORT); / * open a TCP socket (a socket stream Internet) * / IF ((Sockfd = Socket (AF_INET, SOCK_STREAM, 0) <0) Err_sys ("Client: CAN't Open Stream Socket"); / * Connect to * / if (Connect (SockFD, (Struct SockAddr *) & serv_addr, SIZEOF (Serv_addr)) <0) Err_SYS ("Client: CAN't Connect To Server); STR_CLI (STDIN, SOCKFD); / * All Output * / Close (SockFD); exit (0);} Words and signals When using a socket, you can generate three signals. (SIGIO) This signal indicates that a socket is ready for asynchronous I / O. This signal will be sent to all the processes of this socket. These processes are created by calling IOCTL with FiOSetown or SiocSpgrp. Or use F_Setown to call FCNTL to be established. This semaphore is only on this socket on this socket. After calling IOCTL with fioasync or calling Fcntl with Fasync, it can be sent to these processes after asynchronous I / O. (SIGURG) This signal indicates an emergency situation. An emergency is that any one of the data that appears over the bandwidth in the socket. Exceeding the bandwidth indicates that the data arriving in the user process beyond the I / O buffer. (SIGPIPE) This signal indicates that we will no longer write data to the socket, pipe or FIFO. Asynchronous I / O asynchronous I / O allows the process to notify the operating system kernel, if a specified descriptor can perform I / O, the kernel notifies the process. This is typically called the semaphore drive I / O. The number of signals in the kernel notification process is SIGIO. In order to achieve asynchronous I / O, a process must: establish a program that handles SIGIO semaphore. Set the process ID or process group ID and accept the SIGIO semaphore. This is implemented by the fcntl command. The process must be called with DCNTL system to activate asynchronous I / O.

2 Windows Network Programming (Winsock) This section describes Winsock Create a TCP stream sleeve. Winsock's programming and the first part will be very similar. Creating a TCP Jacket The server program opens a stream socket with a socket () function. Specify address format parameters with AF_INET, SOCK_STREAM Specify type parameters. IF ((Winsocket = Socket (AF_INET, SOCK_STREAM, 0) == Invalid_Socket) {WSPrintf (Szerror, Text ("Allocating Socket Failed. Error:% D"), WsageTlasterror ()); MessageBox (Null, Szerror, Text) "Error"), MB_OK; RETURN FALSE;} Using the SockAddr_in structure as an address parameter, name the socket with a bind () function. When you open a socket with a socket () function, this socket has no name, only a descriptor is assigned in an address family name space. In order to let the client socket area separately, a TCP stream sleeve server program must name its socket. But you don't have to name the client's socket with a bind () function. A socket name consists of three parts in the TCP / TP protocol: protocol name, host address, and a port number of characterization applications. These address domains SIN_FAMILY, SIN_ADDR, SIN_PORT are members of the SockAddr_in structure. The SockAddr_in structure must be initialized before calling bind (). The following code demonstrates how to initialize the SockAddr_in structure and call the bind () function. // Fill in the local socket address data local_sin.sin_family = af_INET; local_sin.sin_port = htons (portnum); local_sin.sin_addr.s_addr = htonl (inaddr_any); // Connect the local address and Winsocket IF (Bind (Winsocket, struct sockaddr *) & local_sin, sizeof (local_sin)) == SOCKET_ERROR) {wsprintf (szError, TEXT ( "Binding socket failed Error:.% d"), WSAGetLastError ()); MessageBox (NULL, szError, TEXT ( "Error" ), MB_OK); CloseSocket; Return False;} Using the listen () function listens. In order to prepare a name connection of a TCP stream set server, you must listen to the connection from the client. The following example illustrates how to use the listen () function. IF (Listen (Winsocket, Max_Pending_Connects) == Socket_ERROR) {WSPrintf (Szerror, Text ("Listening to the Client Failed. Error:% D"), WsageTlasterror ()); MessageBox (Null, Szerror, Text ("Error") , MB_OK); CloseSocket; Return False;} Using Accept () accepts the client's connection. TCP stream server socket uses this function to complete the name connection process of the server and client. The accept () function creates a new socket. The initial sleeve opens the socket to continue listening to the port, can be connected, knowing it off.

The server program must be responsible for shutting down the listening socket and all sockets created by the client connection. The following code is an example of an Accept () function application. accept_sin_len = sizeof (accept_sin); // try to connect on receiving a request WinSocket ClientSock = accept (WinSocket, (struct sockaddr *) & accept_sin, (int *) & accept_sin_len); // stop listening for client connections closesocket (WinSocket ); if (clientsock == invalid_socket) {WSPrintf (Szerror, Text ("Accepting Connection With Clientfailed.") Text ("Error:% D"), WsageTlasterror ()); MessageBox (Null, Szerror, Text ("Error" ), MB_OK); RETURN FALSE;} Use the send () and RECV () function to send and accept data. Once the client and the server's socket connection is connected, the above two functions can be exchanged. The Send () function outputs the data to the socket. The RECV () function reads the data from the socket. The following code is an application demonstration of the above two functions. For (; {// Accept data from the client IReturn = Recv (ClientSock, Siz Servera, SizeOf (SZSERVERA), 0); // After confirming the data, display data IF (IReturn == Socket_ERROR) {WSPrintf (Szerror, Text ("NO DATA IS Received.") Text ("Error:% D"), wsagetlasterror ()); MessageBox (Null, Szerror, Text ("Server"), MB_OK; Break;} else == 0) {MessageBox (NULL, TEXT ("Finished Receiving Data"), Text ("Server"), MB_OK; Break;} Else {// Transfer the ASCII string into unicode string for (index = 0; Index <= SIZEOF (SZServera); Index ) SZServerw [=Dex]; // Displays the data received from the client MessageBox (NULL, SZSERVERW, TEXT ("Received from Client"), MB_OK);}} // Send a data IF from the server (Send (ClientSock, "To Client.", Strlen ("To Client.") 1, 0) == Socket_ERROR) {WSPrintf (Szerror, Text ("Sending Data To Error:% D "), wsagetlasterror ()); MessageBox (NULL, SZERROR, TEXT (" ERROR "), MB_OK);} Successfully completed the call () function call does not explain the transmission of data is successful . Use the closockocket () function to disconnect. When the server and client data exchange end, use this function to turn off the socket.

In order to confirm the data in one TCP connection, a program should call the shutdown () function before calling this function. A program should close all open programs before the end of the program, so that the socket resource is returned to the operating system. For TCP streams, when a socket connection is over, the server turns off the socket created by Accept (), but the first listening socket is still open. The listening socket is also turned off before the end of the program. Creating a TCP Jacket The client program opens a stream socket with a socket () function. When calling this function, use AF_INET as an address format parameter to do type parameters with Sock_Stream. Use the SockAddr_in structure as the name parameter to call the connect () function and server connection. The TCP stream sleeve client connects the name and the server through this function. To initialize the SockAddr_in structure before calling the connect () function, this is similar to the bind () function call, but SIN_PORT and SIN_ADDR use the remote socket name instead of local. The following code shows how to connect with the server. // Establish a connection IF of a server socket (Connect (ServerSock, (PsockAddr) == SOCKET_ERROR) == SOCKET_ERROR) {WSPrintf (Szerror, Text ("Connecting to the Server failed. Error:% D" ), Wsagetlasterror ()); MessageBox (NULL, SZERROR, TEXT ("Error"), MB_OK; CloseSocket (ServerSock); Return False;} With Send () and RECV * (function, and server exchange data. Use CloseSocker () The function is closed. The programming Visual C MFC in the third section of the MFC provides a CSocket class to implement network communication. The following figure shows the inheritance relationship of the CSocket class. The following describes the CSocket class related members of the VC implementation socket. use functions (member functions actually inherited from the CAsyncSocket class) of (1) BOOL Create (UINT nSocketPort = 0, int nSocketType = SOCK_STREAM, longlEvent = FD_READ |. FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE, LPCTSTRlpszSocketAddress = NULL) This function is used to establish socket. Where nsocketport is the selected Socket port, it is generally greater than 1023, if the parameter is 0, then the system is selected, the default value is 0; NSocketType is a socket type: SOCK_STREAM is represented as a stream sleeve, and SOCK_DGRAM is represented as a data report, the default value is SOCK_STREAM; LEVENT Identify which work to complete, the default value is fd_read | fd_write | fd_oob | fd_close; lpszsockaddress is a network The address information structure pointer, contains the network address, the default value is NULL.

(2) Bool Bind (uint nsocketport, lpctstr lpszsocketaddress = null) The function of this function is to connect the Socket port with the network address. Parameter meaning is the same. (3) Bool Listen (int NConnectionBackLog = 5) The function of this function is to wait for the Socket request. Where nConnec-tionbacklog represents the length of the wait for the queue, the default value is maximum 5. (4) Virtual Bool Accept (CasyncSocket & ronnectedSocket, SockAddr * LPSOCKADDR = NULL, INT * LPSOCKADDRLEN = NULL) The function of this function is to obtain the first connection request on the queue and establish a socket with the same characteristics as socket. Among them, RConnectedSocket represents a new Socket. (5) BOOL Connect (LPCTSTR LPSZHOSTADDRESS, UINT NHOSTPORT) The function of this function is to make a request. Where lpszhostaddress and Nhostport are the network address and socket port number of the request process. (6) Virtual void close () The function of this function is to close the socket. There are two ways to communicate directly with the CSocket class: one is to implement the CSocketFile class and the Archive class, and the other is to implement the members of the CSocket Receive, Send, ReceiveFrom, Sendto, Listen, and Accept, etc. (these members) The function is actually inherited from the CasyncSocket class). The implementation steps are as follows: Server: construct-> creat-> bind -> listen-> accept-> send-> close; Cilent: Construct -> Creat-> Connect-> receive-> close. Below, use VC code to show how both methods are used to implement Socket programming.

1. Use the CSocketFile class and the Archive class implementation (1) Server program process // Create a socket object CSocket Socksrvr; / / Create a socket Socksrvr.create (NPort) for the above-mentioned socket object; // Start Listen to socksrvr.listen (); // Create a new socket object Csocket SockRecv; // Accept Connect SockSrvr.Accept (SockRecv); // Create File Object Csocketfile File (& SockRecv); // Create an Archive Object CARCHIVE ARIN (& File, CARCHIVE :: Load); / * or * / _ carchive arout (& file, carchive :: store); // use Archive Object Transfer Data Arin >> DWValue; / * Or * / Arout > DWVALUE; in the above program, NPORT is the port number of the socket, and straddr is the IP address of the machine (such as 202.197.1.3 or ftp://redalert.com, etc.), these two variables It is consistent in Server and Client. When the Server process is running to Listen, it is awakened when the Client process is executing Connect, and the last two processes start transmitting data.

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

New Post(0)