In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >
Share
Shulou(Shulou.com)06/02 Report--
There are several methods for interprocess communication mentioned earlier: message signal, pipe pipe, message queue msg, shared memory shm, semaphore sem. It is only suitable for inter-process communication on one host, so how to realize the process communication between two computers? So, take a look at remote process communication.
1 the remote process communication protocol layer allocates "ports" and buffers to the host communication processes of both sides, so as to facilitate the communication between remote processes. 1.1TCP/IP protocol
The following is the correspondence between the OSI reference model and the TCP/IP reference model:
1.1.1 TCP/IP protocol family
The TCP/IP protocol group is generally divided into three parts:
1.Internet Protocol (IP)
2. Transmission Control Protocol (TCP) and user Datagram Protocol (UDP)
3. Applications specially developed by a set of protocols on top of TCP and UDP. They include: TELNET, File transfer Protocol (FTP), Domain name Service (DNS) and simple Mail transfer Program (SMTP) and many other protocols.
Application layer protocol
Telnet File transfer Protocol (FTP and TFTP) simple File transfer Protocol (SMTP) Domain name Service (DNS) and other protocols 2 basic network programming socket standards are extended to window socket and unix socketlinux network programming through the socket interface. Socket is both a special IO and a file descriptor. A complete Socket has a description {protocol, local address, local port, remote address, remote port}; each Socket has a local unique Socket number assigned by the operating system. 2.1 SOCKET classification
Streaming socket (SOCK_STREAM)
Streaming sockets can provide reliable, connection-oriented traffic. It uses the TCP protocol. TCP ensures the correctness and sequence of data transmission.
Datagram socket (SOCK_DGRAM)
Datagram sockets define a connectionless service in which data is transmitted through independent messages, which is disordered, reliable and error-free. Use Datagram protocol UDP protocol.
The original socket.
The original socket allows direct access to lower-level protocols such as IP or ICMP, mainly for testing the implementation of new network protocols.
2.2 programming process
TCP
UDP
The use of specific functions, on their own man.
2.2.1 socket address structure
Focus on the socket address structure:
# include
< netinet/in.h>Struct sockaddr {unsigned short sa_family; / * address family, AF_xxx * / char sa_data [14]; / * 14 bytes protocol address * /}; the value of sa_family. Generally speaking, IPV4 uses "AF_INET" sa_data to include the number of addresses, ports and sockets of some remote computers, in which the data is mixed. Usually we don't use this structure because the address we usually use is the IP+ port number. For example: IP192.168.159.2 port3306. This is how to record the address. Therefore, the following address structure is generally used, and we know that the data types are equivalent and can be converted to each other. # include
< netinet/in.h>Struct sockaddr_in {short int sin_family; / * Internet address family * / unsigned short int sin_port; / * port number * / struct in_addr sin_addr; / * Internet address * / unsigned char sin_zero [8]; / * add 0 (same size as struct sockaddr) * /} 2.2.2 Byte sequence conversion because the byte storage order of variables within each machine is different (some systems are high-level in front, base in the back, and some systems are base in front, high-order in the back), and the data transmitted by the network must be in a unified order. Therefore, for machines that are different from the internal byte representation order and the network byte order, the data must be converted. Htons ()-"Host to Network Short"
Convert host byte order to network byte order (operate on unsigned short 2bytes) htonl ()-- "Host to Network Long"
Convert host byte order to network byte order (4bytes for unsigned long type) ntohs ()-- "Network to Host Short"
Convert network byte order to host byte order (operate on unsigned short 2bytes) ntohl ()-- "Network to Host Long"
Network byte order converted to host byte order (operate on unsigned long type 4bytes) 2.2.3 address format conversion
-linux provides a conversion function for transferring addresses in dotted format to long integers.
Inet_addr () can convert a string that uses numbers and dots to represent IP addresses into an unsigned long integer.
Inet_ntoa () can convert the network byte order into address-structured data.
2.2.4 basic socket calls
Socket () bind () connect ()
Listen () accept () send ()
Recv () sendto () shutdown ()
Recvfrom () close () getsockopt ()
Setsockopt () getpeername ()
Getsockname () gethostbyname ()
Gethostbyaddr () getprotobyname ()
Fcntl ()
Practice 1-TCP
TCP connects, waits for the client to enter, sends the content to the server, and obtains the client address.
Here, getsocketname () means to get a local (own) address
Getpeername () indicates the address (source IP address) of the client on the connection.
Server.c
# include
< sys/types.h># include
< sys/socket.h># include
< netinet/in.h>/ / sockaddr_in#include
< stdio.h># include
< string.h>Int main () {int fd; int clientfd; int ret; pid_t pid; int addrLen = 0; char acbuf [20] = ""; struct sockaddr_in addr = {0}; / / own address struct sockaddr_in clientAddr = {0}; / / the address of the connected client / / 1.socket () fd = socket (PF_INET,SOCK_STREAM,0) If (fd = =-1) {perror ("socket"); return-1;} / / 2.bind () addr.sin_family = AF_INET; addr.sin_port = htons (1234); addr.sin_addr.s_addr = inet_addr ("192.168.159.6"); ret = bind (fd, (struct sockaddr *) & addr,sizeof (struct sockaddr_in)) If (ret = =-1) {perror ("bind"); return-1; / / 3.listen () ret = listen (fd,10); if (ret = =-1) {perror ("listen"); return-1;} / / 4. Blocking waiting for accept () clientfd = accept (fd,NULL,NULL); if (clientfd = =-1) {perror ("accept"); return-1;} / / get client address addrLen = sizeof (struct sockaddr_in); ret = getpeername (clientfd, (struct sockaddr *) & clientAddr, & addrLen); if (ret = =-1) {perror ("getpeername"); return-1 } printf ("client login.\ nip:% s, port:% d\ n", inet_ntoa (clientAddr.sin_addr), ntohs (clientAddr.sin_port)); / / 5. Communication while (1) {memset (acbuf,0,20); if (read (clientfd,acbuf,20) > 0) {printf ("receive:% s\ n", acbuf);}} / / 6.close () close (fd); return 0;}
Client.c
# include # include # include / / sockaddr_in#include # include int main () {int fd; int ret; char acbuf [20] = "; struct sockaddr_in serAddr = {0}; / / 1.socket (); fd = socket (PF_INET,SOCK_STREAM,0); if (fd = =-1) {perror (" socket "); return-1;} / / 2. The address to connect to the connect () server serAddr.sin_family = AF_INET; serAddr.sin_port = htons (1234); serAddr.sin_addr.s_addr = inet_addr ("192.168.159.6"); ret = connect (fd, (struct sockaddr *) & serAddr,sizeof (struct sockaddr_in)); if (ret = =-1) {perror ("connect"); return-1;} / / 3. Communications while (1) {printf ("send:"); fflush (stdout); scanf ("% s", acbuf); if (strcmp (acbuf, "exit") = = 0) {break;} write (fd,acbuf,strlen (acbuf));} / / 4.close () close (fd); return 0;}
Running result:
To make an improvement, the above code can only be connected to one client. Because TCP is point-to-point, one accept () corresponds to one connnect (). To connect to multiple clients, you have to use fork (), one process to specifically block connections waiting for clients, and one to handle communication with connected clients.
The code is as follows:
Server.c
Int main () {int fd; int clientfd; int ret; pid_t pid; int addrLen = 0; char acbuf [20] = ""; char client_addr [100] = ""; struct sockaddr_in addr = {0}; / / own address struct sockaddr_in clientAddr = {0} / / the address of the connected client signal (SIGCHILD,SIG_IGN); / / 1.socket () fd = socket (PF_INET,SOCK_STREAM,0); if (fd = =-1) {perror ("socket"); return-1 } / / an inactive socket still exists, the port binding is disabled, and an error occurs: address already in use. / / caused by the TCP socket TIME_WAIT. Bind returns EADDRINUSE. The status will be retained for 2-4 minutes. / / if (setsockopt (sockfd, SOL_SOCKET, SO_REUSEADDR, & reuse, sizeof (reuse)) < 0) / {/ / perror ("setsockopet error\ n"); / / return-1 / /} / / 2.bind () addr.sin_family = AF_INET; addr.sin_port = htons (1234); addr.sin_addr.s_addr = inet_addr ("192.168.159.6"); ret = bind (fd, (struct sockaddr *) & addr,sizeof (struct sockaddr_in)) If (ret = =-1) {perror ("bind"); return-1;} / / 3.listen () ret = listen (fd,10); if (ret = =-1) {perror ("listen"); return-1 } while (1) {/ / 4. Blocking wait accept () clientfd = accept (fd,NULL,NULL); if (clientfd = =-1) {perror ("accept"); return-1;} pid = fork () / / the parent process is responsible for continuing to listen and wait, and the child process parent and son communicate with the connected client if (pid = =-1) {perror ("fork"); return-1 } if (pid = = 0) / / Child process {/ / obtain the client address addrLen = sizeof (struct sockaddr_in); ret = getpeername (clientfd, (struct sockaddr *) & clientAddr, & addrLen) If (ret = =-1) {perror ("getpeername"); return-1;} sprintf (client_addr, "ip:% s, port:% d\ n",\ inet_ntoa (clientAddr.sin_addr), ntohs (clientAddr.sin_port)) Printf ("client longin.\ n% s\ n", client_addr); / / 5. Communication while (1) {memset (acbuf,0,20); if (read (clientfd,acbuf,20) = = 0) / / client exits {/ / ends the corresponding server process close (clientfd) Exit (0); / / Zombie process} printf ("from% sreceive:% s\ n\ n", client_addr,acbuf) }} else / / parent process {/ / return while, continue to wait}} / / 6.close () close (fd); return 0;}
It must be noted here that every time you end a client, you must turn off the corresponding file descriptor and end the drop child process (zombie process), otherwise, as the client increases, the number of processes will become larger and larger.
Client.c
Int main () {int fd; int ret; int addrLen; char acbuf [20] = "; struct sockaddr_in serAddr = {0}; struct sockaddr_in myAddr = {0}; / / 1.socket (); fd = socket (PF_INET,SOCK_STREAM,0); if (fd = =-1) {perror (" socket "); return-1;} / / 2. Address to connect to the connect () server serAddr.sin_family = AF_INET; serAddr.sin_port = htons (1234); serAddr.sin_addr.s_addr = inet_addr ("192.168.159.6"); ret = connect (fd, (struct sockaddr *) & serAddr,sizeof (struct sockaddr_in)); if (ret = =-1) {perror ("connect"); return-1 } / / get your own address addrLen = sizeof (struct sockaddr_in); ret = getsockname (fd, (struct sockaddr *) & myAddr,&addrLen); if (ret = =-1) {perror ("getsockname"); return-1 } printf ("client---ip:% s, port:% d\ n",\ inet_ntoa (myAddr.sin_addr), ntohs (myAddr.sin_port)); / / 3. Communications while (1) {printf ("send:"); fflush (stdout); scanf ("% s", acbuf); if (strcmp (acbuf, "exit") = = 0) {break;} write (fd,acbuf,strlen (acbuf));} / / 4.close () close (fd); return 0;}
Running result:
Practice 2-UDP
Use the UDP connection to complete the above. However, it is found that with UDP, because it is connectionless, it is not possible to know the source IP address until the packet is received or sent.
So how does UDP know the IP address and port of the client?
1. Send messages to the IP address and port of the high-speed server displayed by the client.
2. Implicitly. The server gets the source IP and port number from the received header.
Server.c
Int main () {int sockfd; int ret; char acbuf [20] = "; char client_addr [20] ="; struct sockaddr_in addr = {0}; struct sockaddr_in clientAddr = {0}; int addrLen = sizeof (struct sockaddr_in); int reuse = 0; / / 1.socket () sockfd = socket (PF_INET,SOCK_DGRAM,0); if (sockfd = =-1) {perror ("socket") Return-1;} / 2.bind () addr.sin_family = AF_INET; addr.sin_port = htons (1235); addr.sin_addr.s_addr = inet_addr ("127.0.0.1"); ret = bind (sockfd, (struct sockaddr *) & addr,addrLen); if (ret = =-1) {perror ("bind"); return-1;} / / 3. Communication while (1) {memset (acbuf,0,20); if (recvfrom (sockfd, acbuf, 100 clientAddr,&addrLen 0, (struct sockaddr *) & clientAddr,&addrLen) =-1) {perror ("recvfrom"); return-1 } / / after receiving the packet from the client, you can know the client address sprintf (client_addr, "ip:% s, port:% d\ n",\ inet_ntoa (clientAddr.sin_addr), ntohs (clientAddr.sin_port)); printf ("receive from% s:% s\ n", client_addr,acbuf) } / / 4.close close (sockfd); return 0;}
Client.c
Int main () {int sockfd; int ret; int addrLen = sizeof (struct sockaddr_in); char acbuf [20] = ""; struct sockaddr_in serAddr = {0}; struct sockaddr_in myAddr = {0}; / / 1.socket () sockfd = socket (PF_INET,SOCK_DGRAM,0); if (sockfd = =-1) {perror ("socket"); return-1 } serAddr.sin_family = AF_INET; serAddr.sin_port = htons (1235); serAddr.sin_addr.s_addr = inet_addr ("127.0.0.1"); / / 2. Communications while (1) {printf ("send:"); fflush (stdout); scanf ("% s", acbuf); if (strcmp (acbuf, "exit") = = 0) {break;} sendto (sockfd, acbuf, 20Power0, (struct sockaddr *) & serAddr,addrLen) / / get your own address ret = getsockname (sockfd, (struct sockaddr *) & myAddr,&addrLen); if (ret = =-1) {perror ("getsockname"); return-1 } printf ("client---ip:% s, port:% d\ n\ n",\ inet_ntoa (myAddr.sin_addr), ntohs (myAddr.sin_port));} / / 3.close close (sockfd); return 0;}
Running result:
You will find that multiple clients can be run directly at this time, because UDP is connectionless, can be one-to-many, many-to-one, many-to-many, as long as the client knows the server address, it can be connected.
Ps: my understanding is limited. I haven't finished my study yet. Please point out any mistakes.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.