TCP/IP network programming based on Linux programming _2 semi-close problem of--I/O stream separation

Source: Internet
Author: User
Tags htons

Theoretical basis
    • Stream: Call fopen Open file after file read and write operation will create a stream, socket network communication will also create a flow, the flow is a data transmission for the purpose of a bridge, in fact, refers to the flow of data, we can understand the data sent and received the path.

    • I/O stream separation: refers to the transmission of data and receive streams separately, controlled by 2 different objects instead of 1 objects. We've talked about 2 I/O flow separation methods, the first: by calling the fork function to create the child process, the parent process is responsible for receiving the data, the child process is responsible for sending the data (Learning note _11). The second is to create a read-mode file pointer with a write-mode file pointer (based on the Linux programming _1) through the invocation of the Fdopen function 2 times.

      -I/O Flow Separation Benefits:
      The first separation method: 1, separate input and output process to reduce the difficulty of implementation (easy maintenance). 2, the input independent output operation can increase the speed (blocking function).
      The second separation method: 1, reduce the implementation difficulty 2, converted to file pointer files operation read-only and write-mode distinguish 3,I/O buffer to improve buffering performance.

Closed problem of fdopen form separation flow
    • Fdopen that is to convert the socket to a file pointer, you can operate the socket like a document operation, but there is an exit and socket the same problem, that is, the service side needs to be semi-closed to secure, and the previous chapter Fdopen direct fclose, which is actually unsafe, This is because the fclose not only closes the file stream, but the socket is also closed. This principle is the same as the previously spoken socket half-closed, then the file stream how to achieve semi-closed it? In fact, we can make a copy of the original file descriptor before creating the file pointer, so that the original descriptor and the copy file description nonalphanumeric reference the same socket, then close one will not destroy the socket, implement a semi-closed environment, and then call the shutdown semi-closed socket. As follows:

      Ways to copy file descriptors:
      int dup (int fildes); Copy file Descriptor Fileds
      int dup2 (int fildes, int fildes2); Copy the file descriptor Fildes and specify the descriptor as Fildes2

    • Instance Code

////Main.cpp//Hello_server////Created by app05 on 15-10-13.//Copyright (c) 2015 APP05. All rights reserved.//#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <arpa/inet.h>#include <sys/socket.h>#define BUF_SIZE 1024x768voidError_handling (Char*message);intMainintargcConst Char* argv[]) {intServ_sock, Clnt_sock;    FILE *READFP; FILE *WRITEFP;structSockaddr_in Serv_adr, Clnt_adr; Socklen_t CLNT_ADR_SZ;CharBuf[buf_size] = {0, };if(ARGC! =2)    {printf("Usage:%s <port> \ n", argv[0]);Exit(1); } Serv_sock = socket (pf_inet, Sock_stream,0);if(Serv_sock = =-1) Error_handling ("socket () error");memset(&serv_adr,0,sizeof(SERV_ADR));    serv_adr.sin_family = af_inet;    SERV_ADR.SIN_ADDR.S_ADDR = htonl (Inaddr_any); Serv_adr.sin_port = htons (Atoi (argv[1]));if(Bind (Serv_sock, (structSOCKADDR *) &serv_adr,sizeof(SERV_ADR)) == -1) Error_handling ("bind () Error");if(Listen (Serv_sock,5) == -1) Error_handling ("Listen () Error"); CLNT_ADR_SZ =sizeof(CLNT_ADR); Clnt_sock = Accept (Serv_sock, (structSOCKADDR *) &clnt_adr, &AMP;CLNT_ADR_SZ);//Convert socket to file* pointer (I/O stream separation), then operate the socket like a file operationREADFP = Fdopen (Clnt_sock,"R"); WRITEFP = Fdopen (DUP (Clnt_sock),"W");//dup Copy File description upper denotes integer unequal    //Send a message to the customer service side    fputs("from server:hi~ client?" \ n ", WRITEFP);fputs("I love all of the world \ n", WRITEFP);fputs("You are awesome! \ n ", WRITEFP);    Fflush (WRITEFP); Shutdown (Fileno (WRITEFP), SHUT_WR);//close socket output streamFclose (WRITEFP);//closes the file stream WRITEFP, and also turns off the corresponding socket send EOF (closes the copy of the DUP copy, the socket also has a reference, so the socket is not destroyed, enabling the semi-closed environment)    //Receive customer service end exit messageFgets (BUF,sizeof(BUF), READFP);fputs(buf, stdout); Fclose (READFP);//Close the file stream READFP and close the socket (the file must be fclose closed after it is opened, so it cannot be closed with shutdown socket only)    return 0;}voidError_handling (Char*message) {fputs(message, stderr); FPUTC (' \ n ', stderr);Exit(1);}
////Main.cpp//Hello_client////Created by app05 on 15-10-13.//Copyright (c) 2015 APP05. All rights reserved.////#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <arpa/inet.h>#include <sys/socket.h>#define BUF_SIZE 1024x768voidError_handling (Char*message);intMainintargcConst Char* argv[]) {intSockCharBuf[buf_size];structSockaddr_in Serv_adr;    FILE *READFP; FILE *WRITEFP;if(ARGC! =3)    {printf("Usage:%s <IP> <port> \ n", argv[0]);Exit(1); } sock = socket (pf_inet, Sock_stream,0);if(Sock = =-1) Error_handling ("socket () error");memset(&serv_adr,0,sizeof(SERV_ADR));    serv_adr.sin_family = af_inet; SERV_ADR.SIN_ADDR.S_ADDR = inet_addr (argv[1]); Serv_adr.sin_port = htons (Atoi (argv[2]));if(Connect (sock,structSOCKADDR *) &serv_adr,sizeof(SERV_ADR)) == -1) Error_handling ("Connect () Error"); READFP = Fdopen (sock,"R"); WRITEFP = Fdopen (sock,"W"); while(1)    {if(Fgets (BUF,sizeof(BUF), readfp) = = NULL)//Receive EOF, return null             Break;fputs(buf, stdout);    Fflush (stdout); }//Send the last string to the server    fputs("from Client:thank you! \ n ", WRITEFP); Fflush (WRITEFP);//semi-closed shutdown is mainly used for the service side, the customer service directly close the general will not have any impact (study note _10)Fclose (WRITEFP); Fclose (READFP);return 0;}voidError_handling (Char*message) {fputs(message, stderr); FPUTC (' \ n ', stderr);Exit(1);}

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

TCP/IP network programming based on Linux programming _2 semi-close problem of--I/O stream separation

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.