Generally, there is only one server in the server, which uses fork () to handle the connection between multiple customers. The basic program is: the server waits for a connection, accepts the connection, and then a child process processes it. This is the next chapter of our examples.
-------------------------------------------------- ------------------------------
Simple server
All of this server does send a string "Hello, World! / N" on streaming. If you want to test this program, you can run the program on a machine and then log in on another machine:
$ Telnet remotehostname 3490
RemotehostName is the name of the machine running.
Server code:
#include
#include
#include
#include
#include
#include
#include
#include
#define myport 3490 / * Defines the user connection port * /
#define backlog 10 / * How much waiting for connection control * /
Main ()
{
INT SOCKFD, New_FD; / * Listen on Sock_fd, New Connection On New_FD
* /
Struct SockAddr_in my_addr; / * my address information * /
Struct SockAddr_in their_addr; / * connector's address information * /
INT SIN_SIZE;
IF ((SockFD = Socket (AF_INET, SOCK_STREAM, 0) == -1) {
PERROR ("socket");
Exit (1);
}
my_addr.sin_family = AF_INET; / * host byte order * / my_addr.sin_port = htons (MYPORT); / * short, network byte order * / my_addr.sin_addr.s_addr = INADDR_ANY; / * auto-fill with my IP * / bzero (& (my_addr.sin_zero) ,; / * zero the rest of the struct * /
IF (Bind (Sockfd, (Struct SockAddr *) & my_addr, sizeof (struct sockaddr)) == -1) {Perror ("bind"); exit (1);} if (listen (sockfd, backlog) == -1 ) {PERROR ("listen"); exit (1);}
While (1) {/ * main accept () loop * / sin_size = sizeof (struct sockaddr_in); if ((new_fd = accept (sockfd, (strunt socketdr *)) == -1) {PERROR "accept"); Continue;} Printf ("Server: Got Connection from% S / N", / inet_ntoa (their_addr.sin_addr)); if (! fork ()) {/ * this is the child process * / if ( Send (new_fd, "hello, world! / n", 14, 0) == -1) PERROR ("send"); close (new_fd); exit (0);} close (new_fd); / * Parent doesn ' T NEED THIS * / WHILE (Waitpid (-1, null, wnohang> 0); / * Clean up child processes * /}} If you are very picky, you must not satisfy all my code is in a big main. () In the function. If you don't like it, you can divide more points. -------------------------------------------------- -------------------------------------------------- ------------------------ Simple customer program This program is simpler than the server. All of this program is connected to the host specified in the command line through the 3490 port, and then get the string sent by the server. Customer code: #include
IF ((SOCKFD = SOCKET (AF_INET, SOCK_STREAM, 0) == -1) {Perror ("socket"); exit (1);} their_addr.sin_family = AF_INET; / * HOST BYTE ORDER * / THEIR_ADDR.SIN_PORT = Htons (port); / * short, network byte order * / their_addr.sin_addr = * (struct in_addr *) HE-> h_addr); Bzero (& (THEIR_ADDR.SIN_ZERO ,; / * Zero the rest of the structure * / IF (Connect (STRUCKD, STRUCKADDR *) & THEIR_ADDR, SIZEOF (STRUCT SOCKADDR)) == -1) {Perror ("Connect"); exit (1);} if ((NumBytes = Recv (Sockfd, BUF, MaxDataSize, 0)) == -1) {Perror ("RECV"); exit (1);} buf [numbytes] = '/ 0'; Printf ("Received:% S", BUF); Close (SockFD) Return 0;} Note that if you run a client before running the server, Connect () will return "Connection Refuse" information, which is very useful. ------------------ -------------------------------------------------- -------------------------------------------------- -
Packets Sockets I don't want to talk more, so I give the code Talker.c and Listener.c. Listener Wait for packets from port 4590 on the machine. Talker sends a packet to a certain machine that contains the contents of the user entered in the command line.
Here is listener.c: #include
We are using unconnected datagram sleeves! The following is Talker.c: #include
IF ((He = gethostByname) == null) {/ * get the host info * / human ("gethostbyname"); exit (1);}
IF ((SockFD = Socket (AF_INET, SOCK_DGRAM, 0) == -1) {Perror ("socket"); exit (1);}
their_addr.sin_family = AF_INET; / * host byte order * / their_addr.sin_port = htons (MYPORT); / * short, network byte order * / their_addr.sin_addr = * ((struct in_addr *) he-> h_addr); bzero ( & (THEIR_ADDR.SIN_ZERO ,; / * Zero the rest of the struct * / if ((NumBytes = Sendto (Sockfd, Argv [2], Strlen (Argv [2]), 0, / (Struct SockAddr *) & their_addr, SIZEOF (STRUCT SOCKADDR)) == -1) {Perror ("Sendto"); exit (1);} Printf ("SENT% D Bytes TO% S / N", NumBytes, INET_NTOA (THEIR_ADDR.SIN_ADDR)); Close (sockfd);} This is all. Run listner on a machine, then run Talker on another machine. Observe their communication! In addition to some of the data sockets I mentioned above In addition to the small details of the connection, I have to say some, when a speaker calls the connect () function and specifies the recipient's address, from this point, the speaker can only go to Connect () The address specified by the function is sent and received. So you don't need to use Sendto () and Recvfrom (), you can use Send () and Recv () instead. ----------- -------------------------------------------------- ------------------- Blocking blocking, you may have heard it. "Block" is "Sleep" technology, you may notice the listener program run in front. It keeps running there, waiting for the packet's arrival. The actual run is that it calls Recvfrom (), then there is no data, so the recvfrom () says "block" until the arrival of the data. Many functions Using blockage. Accept () blocking, all RECV * () functions block. The reason why they can do this is because they are allowed to do so. When you first call socket () to build a set of sets, the kernel is set to block it. If you don't want to block the block, you have to call the function fcntl (): #include
-------------------------------------------------- ------------------------------ SELECT () - Multi-channel synchronization I / O Although this function is a bit strange, it is very it works. Assuming this situation: You are a servers, you keep reading the information on the listening connection while talking on the connection from the connection. No problem, you may say, isn't it an accept () and two RECV ()? Is this easy, friend? If you block the accept ()? How do you attach the RECV () data ? "Use non-blocking sockets!" No! You don't want to exhaust all CPUs? So, how is it? Select () allows you to monitor multiple sockets at the same time. If you want to know, then it will tell you which socket is ready to read, which is ready to write, which socket has an exception. Gossip less, below is select (): #include