0

親愛なるみんな:

Python ベースのソケット クライアントを使用して、文字列データ (つまり、ログ データ) を送信します。

一方、私はサーバー側で文字列データの盗聴に libpcap を使用しています。

しかし、2回目に文字列データをサーバー側に送信すると、クライアント側でエラーが発生しました。

以下のようなエラー:

Traceback (most recent call last):
  File "./udp_client_not_sendback.py", line 21, in <module>
    s.sendall(data) #Send UDP data
  File "/usr/lib/python2.7/socket.py", line 224, in meth
    return getattr(self._sock,name)(*args)
socket.error: [Errno 111] Connection refused

以下は、クライアント側とサーバー側の私のコードです。

クライアント側(Python)

import socket, sys

host = sys.argv[1] #Server IP Address

textport = sys.argv[2] #Server Binding Port

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #socket

try:
    port = int(textport)
except ValueError:
    port = socket.getservbyname(textport, 'udp')

s.connect((host, port)) #connect

while(1):
    print "Enter data to transmit:"

    data = sys.stdin.readline().strip() #UDP data

    s.sendall(data) #Send UDP data

サーバー側(C libpcap)

    pcap_handler_func(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes)
    {
    char timebuf[64];
    char addrstr[64];
    struct ether_header *ethhdr = (struct ether_header *)bytes;
    struct iphdr *ipv4h;
    struct ip6_hdr *ipv6h;
    
    memset(timebuf, 0, sizeof(timebuf));
    if (ctime_r(&h->ts.tv_sec, timebuf) == NULL) {
    return;
    }
    timebuf[strlen(timebuf) - 1] = '\0';
    printf("%s, caplen:%d, len:%d, ", timebuf, h->caplen, h->len);
    ipv4h = (struct iphdr *)(bytes + sizeof(struct ether_header));
    inet_ntop(AF_INET, &ipv4h->saddr, addrstr, sizeof(addrstr));
    printf("src[%s]\n", addrstr);

    return;
    }

    int main()
    {
    pcap_t *p;
    char errbuf[PCAP_ERRBUF_SIZE];
    char cmdstr[] = "udp";
    struct bpf_program bpfprog;
    
    p = pcap_open_live("eth1", 65536, 1, 10, errbuf);

    //Filter
    if (pcap_setfilter(p, &bpfprog) < 0) {
    fprintf(stderr, "%s\n", pcap_geterr(p));
    return 1;
    }

    //Packet action
    if (pcap_loop(p, -1, pcap_handler_func, NULL) < 0) {
    fprintf(stderr, "%s\n", pcap_geterr(p));
    pcap_close(p);
    return 1;
    }

    pcap_close(p);
    return 0;
    }

問題は、サーバー側でソケットをバインドせず、pcap を使用して文字列データをキャプチャすることだと思います。

そのため、2回目にクライアント側でソケットエラーが発生しました。

誰でもこの問題を克服するための提案をしてもらえますか?

ご協力ありがとうございました。

4

1 に答える 1

0

libpcap とそれが使用するキャプチャ メカニズムは、TCP/UDP/IP サーバーを作成するときに使用することを意図していません! これらは、1) パケットのパッシブ キャプチャと (場合によっては libpcap の新しいバージョンで) パケットの注入を許可し、2) リンク層の上で実行され、実装を持たないプロトコルのユーザー モード実装を許可することを目的としています。 OSカーネルで。

libpcap を使用してパケットをリッスンしているマシンでプロセスを実行している場合、特定の TCP または UDP ポートに送信されたパケットを受信するためのソケットがそのマシンに作成されません。

プログラムが問題の UDP ポートに初めてパケットを送信しようとすると、送信先のマシンはおそらくソケットがリッスンしていない UDP ポートにパケットが送信されていることを認識し、ICMP Port Unreachable を返します。メッセージ。送信呼び出しは既に行われています。UDP は信頼性の高い配信保証のないコネクションレス プロトコルであるため、UDP 送信はいかなる種類の応答も待機しませ。パケットがネットワーク上に送信された場合、それは「成功」と見なされます。 UDP レベルで作成されます。

ただし、クライアント プログラムでソケットを接続すると、クライアント マシンの ICMP 実装は、ICMP Port Unreachable メッセージが表示された場合、ソケットにインジケーターを設定して、のUDP パケットを配信できなかったことをプログラムに通知します (次のように)。それを届ける先は何もありませんでした)。そのソケットでの受信試行、またはその後のそのソケットでのパケットの送信試行は、以前に送信されたパケットを配信できなかったことを示す「接続拒否」エラーを返します。また、パケットの送信を 2 回試みても、実際にはパケットが送信されないことも意味します。あなたは別のものを作らなければならないでしょうサーバー上でそのUDPポートをリッスンしているプログラムがない場合は、再びICMP Port Unreachableを取得しますが、パケットの送信に成功すると思います。

そのため、 libpcapを使用したスニファー (サーバーではありません!) アプリケーションで最初のパケットが表示されましたが、2 番目のパケットは表示されませんでした。

したがって、「サーバー側で実行されている実際のサーバーが必要である」というミリムースの言葉は 100% 正しいです。libpcapではなく、通常のソケットを使用して作成し、それが使用する可能性のあるメカニズム(LinuxのAF_PACKETソケット、* BSDおよびOS XのBPFデバイスなど)を使用して、サーバーマシンで実行します。また、libpcap ベースのスニファープログラム、または tcpdump や {Wireshark, TShark} などの他のスニファー プログラムを同時に実行して、ネットワーク上で何が起こっているかを確認することもできます。

于 2013-02-02T22:13:41.047 に答える