[TCP / IP]ネットワークプログラミング:07正常切断ソケット接続

この記事では、単純なTCPソケットハーフクローズ知識について説明します。

一般的に、TCPコネクションの確立が、この時点でのデータ交換を開始していないため、比較的安定であり、データ交換が発生したためと切断手順、いくつかのケースではかもしれない予想外のことが起こりました。

接続によって引き起こさ片側断線の問題

内容以前に述べたように、我々は直接データを受け取ることができなくなり、地元の両端には、もはやデータを送信できることをどの手段、クローズ機能が完全に切断されている呼び出しません。この目的のためにはもはや単なるデータを送信したい場合は、また、直接危機一髪完全に、それは非常にエレガントではなかったから切り離され、データを受信することはできません。したがって、我々は、(半近い)方式「の交換に使用されるデータ・ストリームの閉じた部分のみ」を必要とします。

 一方的に切断

ソケットおよびストリーム(ストリーム)

二つのホストとしても知られているデータ交換ソケット接続、入力した後の状態を確立するための「フロー状態が形成されます。」各ホストは、別の入力を有し、出力ストリーム、及び入力と出力ストリームとストリーム側は2つのI / Oストリームに一致するように形成されています。

 私は2つのソケット/ Oストリームを形成しました

エレガントな切断シャットダウン機能のために

シャットダウンは、双方向I / Oストリームを切断するために使用しました。

書式#include <sysの/ socket.h>に

int型のシャットダウン(int型私たちの靴下、int型のHOWTOを);
     - > 0を返すの成功、失敗を返します- 。1

第2のストリーミングモードパラメータは切断を決定します。

  • SHUT_RD:入力ストリームを切断
  • SHUT_WR:出力ストリームを切断
  • SHUT_RDWR:同時に両方のI / Oストリームを切断

いわゆる切断フローは、実際には、ソケットの間の通路は、I / Oバッファを切り離します。ソケットがデータを送信することができない、出力ストリームオフSHUT_WRが、しかし、このように、SHUT_RD入力ストリームを切断し、ソケットは、受信されたデータ入力バッファが消去され、入力は、関連する関数を呼び出すことができない場合でも、データを受信することができません出力バッファが残っている場合、データはまだ先ホストに送信することができます。

なぜあなたは、ハーフクローズが必要なのか

セミクローズドの主な役割は二つあります。その他、本発明の端場合は、まず、反対側を可能にするために、ターゲットホストへのデータ送信の信号(EOF)エンドを送信する送信データが存在していたが、他のアクション(この関数はまた、クローズ動作を行うことができる)とすることができる感知データ送信はまた、唯一の出力ストリームをフィードバック情報端末、コールシャットダウン機能をオフに受信する必要が完了した後(半閉じ、それがクローズ機能を達成することができません)。

セミクローズドファイル転送プログラム

次のプログラムは、ファイル転送の接合部に基づいており、ハーフクローズハーフクローズアクションのシャットダウンを表示するために行います。

 図トランスポートストリームファイル

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4 #include <unistd.h>
 5 #include <arpa/inet.h>
 6 #include <sys/socket.h>
 7 
 8 #define BUF_SIZE 30
 9 void error_handling(char *message);
10 
11 int main(int argc, char *argv[])
12 {
13     int serv_sd, clnt_sd;
14     FILE * fp;
15     char buf[BUF_SIZE];
16     int read_cnt;
17     
18     struct sockaddr_in serv_adr, clnt_adr;
19     socklen_t clnt_adr_sz;
20     
21     if(argc!=2) {
22         printf("Usage: %s <port>\n", argv[0]);
23         exit(1);
24     }
25     
26     fp=fopen("file_server.c", "rb"); 
27     serv_sd=socket(PF_INET, SOCK_STREAM, 0);   
28     
29     memset(&serv_adr, 0, sizeof(serv_adr));
30     serv_adr.sin_family=AF_INET;
31     serv_adr.sin_addr.s_addr=htonl(INADDR_ANY);
32     serv_adr.sin_port=htons(atoi(argv[1]));
33     
34     bind(serv_sd, (struct sockaddr*)&serv_adr, sizeof(serv_adr));
35     listen(serv_sd, 5);
36     
37     clnt_adr_sz=sizeof(clnt_adr);    
38     clnt_sd=accept(serv_sd, (struct sockaddr*)&clnt_adr, &clnt_adr_sz);
39     
40     while(1)
41     {
42         read_cnt=fread((void*)buf, 1, BUF_SIZE, fp);
43         if(read_cnt<BUF_SIZE)
44         {
45             write(clnt_sd, buf, read_cnt);
46             break;
47         }
48         write(clnt_sd, buf, BUF_SIZE);
49     }
50     
51     shutdown(clnt_sd, SHUT_WR);    
52     read(clnt_sd, buf, BUF_SIZE);
53     printf("Message from client: %s \n", buf);
54     
55     fclose(fp);
56     close(clnt_sd); close(serv_sd);
57     return 0;
58 }
59 
60 void error_handling(char *message)
61 {
62     fputs(message, stderr);
63     fputc('\n', stderr);
64     exit(1);
65 }
flie_server
file_client

 运行结果

おすすめ

転載: www.cnblogs.com/Glory-D/p/12112875.html