c++ネットワークプログラミング(7)LINUXでのsocketプログラミングソケットベースの標準I/O関数使用とfopen,feof,fgets,fputs関数使用法

17823 ワード


原文作者:aircraft
テキストリンク:https://www.cnblogs.com/DOMLX/p/9614820.html
 
一.標準I/O
1,標準I/Oとは?実際には、fopen、feof、fgetc、fputsなどのC言語のファイル操作関数を指し、プラットフォームとは関係ありません.
2,ネットワーク通信で標準I/Oを使用するメリット:
  • 良好な移植性.良好な移植性これは多くの解釈を必要とせず、I/O関数だけでなく、すべての標準関数が良好な移植性を持っている.なぜなら、これらの関数はすべてのオペレーティングシステム(コンパイラ)をサポートするためにANSI C規格に従って定義されているからです.
  • 標準I/O関数は、バッファを使用してパフォーマンスを向上させることができます.ネットワーク通信ではread,write転送データはソケットバッファが1つしかありませんが、標準I/O転送を使用するとI/Oバッファとソケットバッファの2つの追加バッファがあります.I/Oバッファの使用は、主にパフォーマンスを向上させるために必要なデータが多いほど顕著になります.なぜなら、一度により多くのデータを送信するには、同じデータを複数回送信するよりもパフォーマンスが高いからです.1回のデータを送信すると1つのパケットに対応し、パケットのヘッダ情報はデータサイズに関係なく大きいことが多い.

  • 3,ネットワーク通信で標準I/Oを使用する欠点:
  • は双方向通信が容易ではない.
  • は、fflush関数を頻繁に呼び出す場合がある.
  • は、FILE構造体ポインタとしてファイル記述子を返す必要がある.

  • 4、変換関数
    //ファイル記述子を標準I/O関数で使用するFILE構造体ポインタFILE*fdopen(int fildes,const char*mode)に変換する.成功時に変換されたFILE構造体ポインタを返し、失敗してNULLを返します.
    //FILE構造体ポインタをファイル記述子int fileno(FILE*stream)に変換する.変換されたファイル記述子が正常に返され、-1が失敗しました.
    注記:ソケットには標準I/Oが使われていますが、主に大量のデータを転送する必要がある場合に使われています.追加コードを書く必要があるため、想像していたほどよく使われていません.
    fdopen関数の簡単な例を先に示します.
    #include 
    main()
    {
        FILE * fp = fdopen(0, "w+");
        fprintf(fp, "%s
    ", "hello!"); fclose(fp); }

     
    filenoの例:
    #include 
    main()
    {
         FILE   *fp;
         int   fd;
         fp = fopen("/etc/passwd", "r");
         fd = fileno(fp);
         printf("fd = %d
    ", fd); fclose(fp); }

     
    5.fgetsとfputs関数:
    1.fgets()
    機能:ファイルから文字列を読み込む
    定義:char*fgets(char*s,int size,FILE*stream)説明:fgets()は、パラメータstreamが指すファイルから文字を読み込んでパラメータsが指すメモリ空間に格納するために使用されます.
    改行文字まで読んだり、ファイルの最後まで読んだり、size-1文字まで読んだりするまで、最後にNULLを入れてファイルの最後にします.
    戻り値:sのポインタが正常に返されませんでしたNULLの戻りに失敗しました
     
     
    2.fputs()
     
    機能:指定した文字列をファイルに書き込む
    定義:char*fputs(const*char s,FILE*stream)説明:fputs()は、sが指す文字列をパラメータstreamが指すファイルに書き込むための戻り値です.書き込み文字列の個数を正常に返すと、EOFに戻りません.
     
     
    サンプルコード:
     
    include 
     
    int main()
    {
    int str[100];
    fputs(fgets(str, 100, strin), strout);
     
    return 0;
    }

     
    6.feof紹介:
    1.stdio.hにおけるマクロ定義
    #define  _IOEOF  0x0010  #define  feof(_stream)  ((_stream)->_flag & _IOEOF)
    2.feofの使用:
    feofは検出ストリーム上のファイル終端子を使用し、その戻り値は2つあります.ファイル終端に遭遇した場合、関数値はゼロ値ではありません.そうしないと、関数値は0になります.
    注:ここでのファイル終了フラグはEOF、EOFの16進コードは0 xFF(10進-1)で、テキストファイルに特化しています.テキストファイルにデータがASCIIコード値として格納されているため、普通文字のASCIIコードの範囲は32~127(10進)であり、EOFと衝突しないため、そのまま使用できます.ただし、バイナリファイルでは、データが-1になる可能性があるため、EOFでバイナリファイルの終了フラグとすることはできず、feof関数で判断できる.
     
     
    これらの標準I/O関数の速度は通常の関数よりずっと速いことに注意しましたが、毎回使うわけではありません.
     
    二.標準I/O関数に基づいてソケットサービスとクライアントの通信を実現
    LINUXサービス:
    #include 
    #include 
    #include <string.h>
    #include 
    #include 
    #include 
    
    #define BUF_SIZE 1024
    void error_handling(char *message);
    
    int main(int argc, const char * argv[]) {
        int serv_sock, clnt_sock;
        char message[BUF_SIZE];
        int str_len, i;
    
        struct sockaddr_in serv_adr, clnt_adr;
        socklen_t clnt_adr_sz;
        FILE *readfp;
        FILE *writefp;
    
        if(argc != 2)
        {
            printf("Usage: %s  
    ", 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, (struct sockaddr *) &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); for (i = 0; i < 5; i++) { clnt_sock = accept(serv_sock, (struct sockaddr *) &clnt_adr, &clnt_adr_sz); if(clnt_sock == -1) error_handling("accept() error"); else printf("Connected client %d
    ", i+1); // FILE readfp = fdopen(clnt_sock, "r"); writefp = fdopen(clnt_sock, "w"); while (!feof(readfp)) { // I/O fgets(message, BUF_SIZE, readfp);// read, fputs(message, writefp); // write, fflush(writefp); // , , } fclose(readfp); fclose(writefp); } close(serv_sock); return 0; } void error_handling(char *message) { fputs(message, stderr); fputc('
    ', stderr); exit(1); }

     
    LINUXのクライアント:
     
    #include 
    #include 
    #include <string.h>
    #include 
    #include 
    #include 
    
    #define BUF_SIZE 1024
    void error_handling(char *message);
    
    int main(int argc, const char * argv[]) {
        int sock;
        char message[BUF_SIZE];
        int str_len;
        struct sockaddr_in serv_adr;
        FILE *readfp;
        FILE *writefp;
    
        if(argc != 3)
        {
            printf("Usage: %s   
    ", 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, (struct sockaddr *) &serv_adr, sizeof(serv_adr)) == -1) error_handling("connect() error"); else puts("Connected ..............."); readfp = fdopen(sock, "r"); writefp = fdopen(sock, "w"); while (1) { fputs("Input message(Q to quit): ", stdout); fgets(message, BUF_SIZE, stdin); if (!strcmp(message, "q
    ") || !strcmp(message, "Q
    ")) break; fputs(message, writefp); fflush(writefp); fgets(message, BUF_SIZE, readfp); printf("Message from server : %s", message); } fclose(writefp); fclose(readfp); return 0; } void error_handling(char *message) { fputs(message, stderr); fputc('
    ', stderr); exit(1); }

     
     
     
     
    最後に一言.このネットプログラミング入門シリーズのブログは連載学習で、興味があるのは私のブログの他の編を見ることができます...c++ネットワークプログラミングレッスン入門超詳細チュートリアル---ディレクトリ
     
    さて今日はネットプログラミングの勉強はここで終わり、小さな飛行機は撤収してご飯を食べに行きます.、、多くの人は大学がすべてとても迷って何を学ぶのが良いことを知らないで、、、、、彼のを管理して、そんなに多く何を考えて、先に学んで更に言って、技术に対して偏见があるならば、それではあなたの领域はこれに限られます---
     
     
     
     
    参考ブログ:https://blog.csdn.net/u010223072/article/details/48316117
    参考ブログ:https://blog.csdn.net/qq_32103869/article/details/50834629
    参考書:『TCP/IPネットワークプログラミング--尹聖雨』