UDPデータ損失率

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: UDPデータ損失率

#31

投稿記事 by softya(ソフト屋) » 7年前

と言うことは史上最悪のデスペナさんの送信側プログラムに何らかの問題があると考えるのが妥当かと思います。
ところでWinscok2はws2_32.libを使われていますよね?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

YuO
記事: 941
登録日時: 8年前
住所: 東京都世田谷区

Re: UDPデータ損失率

#32

投稿記事 by YuO » 7年前

ひとつ思ったのですが,「送信エラー」等の出力時に,WSAGetLastError APIの値は確認していますか。
WSAStartupでも確認せずにループをしているあたり,エラー処理が全然なされていないのではないか,という気がしますが。
# WSAStartupの失敗は致命的なエラー扱いでいいと思う……。

史上最悪のデスペナ
記事: 521
登録日時: 8年前

Re: UDPデータ損失率

#33

投稿記事 by 史上最悪のデスペナ » 7年前

最初にWinsockについて調べたときにここ
WinSockを使うにはちょっとクセがあって、[wsock32.lib]というライブラリーにリンクせねばなりません。
と書いてあったのでそれをリンクしてました。それ以降、他のサイトではその部分を流していたので・・・・・
ws2_32.libに書き換えましたが、
25%→45%(9回/20回)になっただけでした

値は全く確認してませんね、確かに。それを入れてきます


追記
以降、特に明記しない限り
    送信:私の送信プログラムが送信すること
    受信:私の受信プログラムが受信すること
とします

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: UDPデータ損失率

#34

投稿記事 by softya(ソフト屋) » 7年前

ws2_32.libはWinSock2.h用でwsock32.libはWinSock.h用です。バージョンが違うので注意して下さい。
それと連続5回通信とかの機能を入れてみてください。送信文字列はHELLO0~HELLO4と変化するのが望ましいです。
これは、一回の送信毎に確率的に失敗するのか、何らかの初期化周りが成功すれば連続送信が成功するのか知りたいためです。

[追記]史上最悪のデスペナさんがリリースビルドしたプログラムを添付してもらって良いですか?
ソースレベルではなくexeレベルでチェックしたいです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

史上最悪のデスペナ
記事: 521
登録日時: 8年前

Re: UDPデータ損失率

#35

投稿記事 by 史上最悪のデスペナ » 7年前

softya(ソフト屋) さんが書きました:[追記]史上最悪のデスペナさんがリリースビルドしたプログラムを添付してもらって良いですか?
ソースレベルではなくexeレベルでチェックしたいです。
ごめんなさい、これのやり方がわかりません。教えてください

合ってるかはわかりませんが、DebugモードではなくReleaseモードでビルドしたときに以下のエラーが出ました

1>------ ビルド開始: プロジェクト: 01, 構成: Release Win32 ------
1>01.obj : error LNK2001: 外部シンボル "__imp__closesocket@4" は未解決です。
1>01.obj : error LNK2001: 外部シンボル "__imp__socket@12" は未解決です。
1>01.obj : error LNK2001: 外部シンボル "__imp__WSACleanup@0" は未解決です。
1>01.obj : error LNK2001: 外部シンボル "__imp__sendto@24" は未解決です。
1>01.obj : error LNK2001: 外部シンボル "__imp__htons@4" は未解決です。
1>01.obj : error LNK2001: 外部シンボル "__imp__inet_addr@4" は未解決です。
1>01.obj : error LNK2001: 外部シンボル "__imp__WSAStartup@8" は未解決です。
1>C:\Users\TO\Desktop\WinSock\05.UDP-1(単純) - コピー\Client\Release\01.exe : fatal error LNK1120: 外部参照 7 が未解決です。
========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========
最後に編集したユーザー 史上最悪のデスペナ on 2012年1月23日(月) 18:18 [ 編集 1 回目 ]

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: UDPデータ損失率

#36

投稿記事 by softya(ソフト屋) » 7年前

送信プログラムをリリースビルドして出来上がったexeをZIP圧縮して、ここに添付してもらうだけで良いです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

史上最悪のデスペナ
記事: 521
登録日時: 8年前

Re: UDPデータ損失率

#37

投稿記事 by 史上最悪のデスペナ » 7年前

史上最悪のデスペナ さんが書きました:合ってるかはわかりませんが、DebugモードではなくReleaseモードでビルドしたときに以下のエラーが出ました

1>------ ビルド開始: プロジェクト: 01, 構成: Release Win32 ------
1>01.obj : error LNK2001: 外部シンボル "__imp__closesocket@4" は未解決です。
1>01.obj : error LNK2001: 外部シンボル "__imp__socket@12" は未解決です。
1>01.obj : error LNK2001: 外部シンボル "__imp__WSACleanup@0" は未解決です。
1>01.obj : error LNK2001: 外部シンボル "__imp__sendto@24" は未解決です。
1>01.obj : error LNK2001: 外部シンボル "__imp__htons@4" は未解決です。
1>01.obj : error LNK2001: 外部シンボル "__imp__inet_addr@4" は未解決です。
1>01.obj : error LNK2001: 外部シンボル "__imp__WSAStartup@8" は未解決です。
1>C:\Users\TO\Desktop\WinSock\05.UDP-1(単純) - コピー\Client\Release\01.exe : fatal error LNK1120: 外部参照 7 が未解決です。
========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========
編集が遅かったのでお返事を既に頂いていたようですね。
普段はDebugモードを使用しているのですが、Debugモードではエラーが出なかったのにReleaseモードでは以上のようなエラーが出てビルドできませんでした

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: UDPデータ損失率

#38

投稿記事 by softya(ソフト屋) » 7年前

ライブラリの指定はDebugとReleaseで別に行う必要があります。

環境依存な方法としては
#pragma comment(lib,"ws2_32.lib")
とソースプログラム中に書いてしまう方法もあります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

史上最悪のデスペナ
記事: 521
登録日時: 8年前

Re: UDPデータ損失率

#39

投稿記事 by 史上最悪のデスペナ » 7年前

よろしくお願いします
01.zip
(3.37 KiB) ダウンロード数: 28 回

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: UDPデータ損失率

#40

投稿記事 by softya(ソフト屋) » 7年前

出力先のポート番号は幾つでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

史上最悪のデスペナ
記事: 521
登録日時: 8年前

Re: UDPデータ損失率

#41

投稿記事 by 史上最悪のデスペナ » 7年前

例のツールのポート番号が4000だったのでそれにあわせたままです

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: UDPデータ損失率

#42

投稿記事 by softya(ソフト屋) » 7年前

試した所100%届きました。
と言うことは史上最悪のデスペナさんのOS、ファイアウォール、ウィルス対策ソフト,winsock2のdllあたりが怪しいと思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

史上最悪のデスペナ
記事: 521
登録日時: 8年前

Re: UDPデータ損失率

#43

投稿記事 by 史上最悪のデスペナ » 7年前

OSに関してはどうしようもないのですが・・・・・・
ファイアウォールとウィルス対策ソフトは切ったりしてやってみます。
dllはどっかから落としてくるのですかね?

史上最悪のデスペナ
記事: 521
登録日時: 8年前

Re: UDPデータ損失率

#44

投稿記事 by 史上最悪のデスペナ » 7年前

softya(ソフト屋) さんが書きました:それと連続5回通信とかの機能を入れてみてください。送信文字列はHELLO0~HELLO4と変化するのが望ましいです。
これは、一回の送信毎に確率的に失敗するのか、何らかの初期化周りが成功すれば連続送信が成功するのか知りたいためです。
まだ、これ出来てませんがファイアウォールやセキュリティソフトを切ったときの送信テストは以下のようになりました

コード:

セキュリティソフト:なし  ファイアウォール:あり・・・・・・・・・・40%(8回/20回)
セキュリティソフト:あり  ファイアウォール:なし・・・・・・・・・・20%(4回/20回)
セキュリティソフト:なし  ファイアウォール:なし・・・・・・・・・・30%(6回/20回)

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: UDPデータ損失率

#45

投稿記事 by softya(ソフト屋) » 7年前

デバッカを介さず直接exeを起動しても同じぐらいの確率ですか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

史上最悪のデスペナ
記事: 521
登録日時: 8年前

Re: UDPデータ損失率

#46

投稿記事 by 史上最悪のデスペナ » 7年前

softya(ソフト屋) さんが書きました:デバッカを介さず直接exeを起動しても同じぐらいの確率ですか?
はい。そうです
史上最悪のデスペナ さんが書きました:

コード:

while(1)
    {
        SendFlag = sendto( SendSock, "HELLO", 5, 0, (struct sockaddr *)&ServerAddr, sizeof(ServerAddr) );
        if( SendFlag == 5 ) break;
    }
部分を

コード:

	sendto( SendSock, "HELLO-0", 7, 0, (struct sockaddr *)&ServerAddr, sizeof(ServerAddr) );
	sendto( SendSock, "HELLO-1", 7, 0, (struct sockaddr *)&ServerAddr, sizeof(ServerAddr) );
	sendto( SendSock, "HELLO-2", 7, 0, (struct sockaddr *)&ServerAddr, sizeof(ServerAddr) );
	sendto( SendSock, "HELLO-3", 7, 0, (struct sockaddr *)&ServerAddr, sizeof(ServerAddr) );
	sendto( SendSock, "HELLO-4", 7, 0, (struct sockaddr *)&ServerAddr, sizeof(ServerAddr) );
のように変えたところ、この塊が送信されるか、一個も送信されないかのどちらかでした。
今回の確率(セキュリティソフト・ファイアウォールあり)・・・・・・・55%(11回/20回)

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: UDPデータ損失率

#47

投稿記事 by softya(ソフト屋) » 7年前

既に聞いたことのない未知の領域ですので、こうなったら細かい所をチェックして行きましょう。

(1)windows updateを徹底的に行う。

(2)winsock2のバージョンを確認。
「WinSockの情報」
http://wisdom.sakura.ne.jp/system/winap ... Sock2.html

(3)WSAGetLastErrorなどでエラーをチェックしまくる。
closesocket()などもチェックして下さい。もしかしたらパケット送出に失敗した戻り値が戻るかも知れません。
リトライはしなくて良いですが、エラーの詳細を表示して終了して下さい。

これらで治らないならOSの再インストールなど大掛かりな作業をするしか無い気がしてきました。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

史上最悪のデスペナ
記事: 521
登録日時: 8年前

Re: UDPデータ損失率

#48

投稿記事 by 史上最悪のデスペナ » 7年前

(1)windows updateを徹底的に行う。→クリア

(2)winsock2のバージョンを確認。→

コード:

printf("バージョン = %d.%d\n記述 = %s\n状態 = %s\n" ,
		(BYTE)wsaData.wHighVersion , wsaData.wHighVersion >> 8 ,
		wsaData.szDescription ,	wsaData.szSystemStatus
	);
より2.2と表示された

(3)WSAGetLastErrorなどでエラーをチェックしまくる。→
意味不明な挙動

コード:

#include <stdio.h>
#include <winsock2.h>

int main()
{
	WSAData wsaData;

	SOCKET SendSock, RecvSock;
	struct sockaddr_in ServerAddr;

	int Flag;

	WSAStartup(MAKEWORD(2,0), &wsaData);
	Flag = WSAGetLastError();
	printf("%d",Flag);
	SendSock = socket(AF_INET, SOCK_DGRAM, 0);
	printf("%d",Flag);

	RecvSock = socket(AF_INET, SOCK_DGRAM, 0);
	printf("%d",Flag);

	ServerAddr.sin_family = AF_INET;
	ServerAddr.sin_port = htons(4000);
	ServerAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");

/*	while(1)
	{
		SendFlag = sendto( SendSock, "HELLO", 5, 0, (struct sockaddr *)&ServerAddr, sizeof(ServerAddr) );
		if( SendFlag == 5 ) break;
	}
*/
	sendto( SendSock, "HELLO-0", 7, 0, (struct sockaddr *)&ServerAddr, sizeof(ServerAddr) );
	sendto( SendSock, "HELLO-1", 7, 0, (struct sockaddr *)&ServerAddr, sizeof(ServerAddr) );
	sendto( SendSock, "HELLO-2", 7, 0, (struct sockaddr *)&ServerAddr, sizeof(ServerAddr) );
	sendto( SendSock, "HELLO-3", 7, 0, (struct sockaddr *)&ServerAddr, sizeof(ServerAddr) );
	sendto( SendSock, "HELLO-4", 7, 0, (struct sockaddr *)&ServerAddr, sizeof(ServerAddr) );
	printf("%d",Flag);

	closesocket( SendSock );
	closesocket( RecvSock );
	printf("%d",Flag);

	WSACleanup();
	printf("%d",Flag);

	return 0;
}
だと、すべて0なのに送れなかったり、送れてもHello0だけだったり。

コード:

#include <stdio.h>
#include <winsock2.h>

int main()
{
	WSAData wsaData;

	SOCKET SendSock, RecvSock;
	struct sockaddr_in ServerAddr;

	int Flag;

	WSAStartup(MAKEWORD(2,0), &wsaData);
	Flag = WSAGetLastError();
	printf("%d\n",Flag);
	SendSock = socket(AF_INET, SOCK_DGRAM, 0);
	Flag = WSAGetLastError();
	printf("%d\n",Flag);

	RecvSock = socket(AF_INET, SOCK_DGRAM, 0);
	Flag = WSAGetLastError();
	printf("%d\n",Flag);

	ServerAddr.sin_family = AF_INET;
	ServerAddr.sin_port = htons(4000);
	ServerAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");

/*	while(1)
	{
		SendFlag = sendto( SendSock, "HELLO", 5, 0, (struct sockaddr *)&ServerAddr, sizeof(ServerAddr) );
		if( SendFlag == 5 ) break;
	}
*/
	sendto( SendSock, "HELLO-0", 7, 0, (struct sockaddr *)&ServerAddr, sizeof(ServerAddr) );
	Flag = WSAGetLastError();
	printf("%d\n",Flag);
	sendto( SendSock, "HELLO-1", 7, 0, (struct sockaddr *)&ServerAddr, sizeof(ServerAddr) );
	Flag = WSAGetLastError();
	printf("%d\n",Flag);
	sendto( SendSock, "HELLO-2", 7, 0, (struct sockaddr *)&ServerAddr, sizeof(ServerAddr) );
	Flag = WSAGetLastError();
	printf("%d\n",Flag);
	sendto( SendSock, "HELLO-3", 7, 0, (struct sockaddr *)&ServerAddr, sizeof(ServerAddr) );
	Flag = WSAGetLastError();
	printf("%d\n",Flag);
	sendto( SendSock, "HELLO-4", 7, 0, (struct sockaddr *)&ServerAddr, sizeof(ServerAddr) );
	Flag = WSAGetLastError();
	printf("%d\n",Flag);

	closesocket( SendSock );
	closesocket( RecvSock );
	Flag = WSAGetLastError();
	printf("%d\n",Flag);

	WSACleanup();
	Flag = WSAGetLastError();
	printf("%d\n",Flag);

	return 0;
}
こうすると全て100%送信可。ただし、ブレイクポイントをreturn0に設定しておき、ブレイクポイントでの強制終了すると
次の数回は送れないか、またはHELLO0のみの送信となる

という結果になりました

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: UDPデータ損失率

#49

投稿記事 by softya(ソフト屋) » 7年前

WSAGetLastError()だけでなく全部の戻り値をチェックして下さい。

あとServerAddrの内容をクリアしたらどうなります?
memset(&ServerAddr, 0x00, siezof(ServerAddr));
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

史上最悪のデスペナ
記事: 521
登録日時: 8年前

Re: UDPデータ損失率

#50

投稿記事 by 史上最悪のデスペナ » 7年前

softya(ソフト屋) さんが書きました:WSAGetLastError()だけでなく全部の戻り値をチェックして下さい。
WSAGetLastError()を無くして戻り値だけのチェック

コード:

#include <stdio.h>
#include <winsock2.h>

int main()
{
	WSAData wsaData;

	SOCKET SendSock, RecvSock;
	struct sockaddr_in ServerAddr;

	int InitFlag, BindFlag, SendFlag;

	InitFlag = WSAStartup(MAKEWORD(2,0), &wsaData);
	switch(InitFlag)
	{
		case WSASYSNOTREADY:
			printf("ネットワークへの接続準備ができていない");
			break;
		case WSAVERNOTSUPPORTED:
			printf("要求した WinSock のバージョンはこのシステムで提供されていない");
			break;
		case WSAEINPROGRESS:
			printf("ブロッキング操作の実行中であるまたはサービスプロバイダがコールバック関数を処理している");
			break;
		case WSAEPROCLIM:
			printf("WinSock が同時に処理できる最大プロセスに達成した");
			break;
		case WSAEFAULT:
			printf("lpWSAData は有効なポインタではない");
			break;
	}
	SendSock = socket(AF_INET, SOCK_DGRAM, 0);
		if( SendSock == INVALID_SOCKET ) printf("送信ソケット作成エラー");
	RecvSock = socket(AF_INET, SOCK_DGRAM, 0);
		if( RecvSock == INVALID_SOCKET ) printf("受信ソケット作成エラー");

	ServerAddr.sin_family = AF_INET;
	ServerAddr.sin_port = htons(4000);
	ServerAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");

	int len = sendto( SendSock, "HELLO-0", 7, 0, (struct sockaddr *)&ServerAddr, sizeof(ServerAddr) );
	sendto( SendSock, "HELLO-1", 7, 0, (struct sockaddr *)&ServerAddr, sizeof(ServerAddr) );
	sendto( SendSock, "HELLO-2", 7, 0, (struct sockaddr *)&ServerAddr, sizeof(ServerAddr) );
	sendto( SendSock, "HELLO-3", 7, 0, (struct sockaddr *)&ServerAddr, sizeof(ServerAddr) );
	sendto( SendSock, "HELLO-4", 7, 0, (struct sockaddr *)&ServerAddr, sizeof(ServerAddr) );
	if( len == SOCKET_ERROR ) printf("SOCKET_ERROR");
	if( len < 7 ) printf("Short");

	int Flag = closesocket( SendSock );
		if( Flag == SOCKET_ERROR ) printf("SendSock_CLOSE_ERROR");
	Flag = closesocket( RecvSock );
		if( Flag == SOCKET_ERROR ) printf("RecvSock_CLOSE_ERROR");

	WSACleanup();

	return 0;
}
何も表示されないのにもかかわらず成功率50%(3回/6回)

WSAGetLastError()と戻り値のチェック

コード:

#include <stdio.h>
#include <winsock2.h>

int main()
{
	WSAData wsaData;

	SOCKET SendSock, RecvSock;
	struct sockaddr_in ServerAddr;

	int InitFlag, ErrorFlag;

	InitFlag = WSAStartup(MAKEWORD(2,0), &wsaData);
		ErrorFlag = WSAGetLastError();
		printf("%d\n",ErrorFlag);
		switch(InitFlag)
		{
			case WSASYSNOTREADY:
				printf("ネットワークへの接続準備ができていない");
				break;
			case WSAVERNOTSUPPORTED:
				printf("要求した WinSock のバージョンはこのシステムで提供されていない");
				break;
			case WSAEINPROGRESS:
				printf("ブロッキング操作の実行中であるまたはサービスプロバイダがコールバック関数を処理している");
				break;
			case WSAEPROCLIM:
				printf("WinSock が同時に処理できる最大プロセスに達成した");
				break;
			case WSAEFAULT:
				printf("lpWSAData は有効なポインタではない");
				break;

		}
	SendSock = socket(AF_INET, SOCK_DGRAM, 0);
		ErrorFlag = WSAGetLastError();
		printf("%d\n",ErrorFlag);
		if( SendSock == INVALID_SOCKET ) printf("送信ソケット作成エラー");
	RecvSock = socket(AF_INET, SOCK_DGRAM, 0);
		ErrorFlag = WSAGetLastError();
		printf("%d\n",ErrorFlag);
		if( RecvSock == INVALID_SOCKET ) printf("受信ソケット作成エラー");

	ServerAddr.sin_family = AF_INET;
	ServerAddr.sin_port = htons(4000);
	ServerAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");

/*	while(1)
	{
		SendFlag = sendto( SendSock, "HELLO", 5, 0, (struct sockaddr *)&ServerAddr, sizeof(ServerAddr) );
		if( SendFlag == 5 ) break;
	}
*/
	int len = sendto( SendSock, "HELLO-0", 7, 0, (struct sockaddr *)&ServerAddr, sizeof(ServerAddr) );
	sendto( SendSock, "HELLO-1", 7, 0, (struct sockaddr *)&ServerAddr, sizeof(ServerAddr) );
	sendto( SendSock, "HELLO-2", 7, 0, (struct sockaddr *)&ServerAddr, sizeof(ServerAddr) );
	sendto( SendSock, "HELLO-3", 7, 0, (struct sockaddr *)&ServerAddr, sizeof(ServerAddr) );
	sendto( SendSock, "HELLO-4", 7, 0, (struct sockaddr *)&ServerAddr, sizeof(ServerAddr) );
		ErrorFlag = WSAGetLastError();
		printf("%d\n",ErrorFlag);
		if( len == SOCKET_ERROR ) printf("SOCKET_ERROR");
		if( len < 7 ) printf("Short");


	int Flag = closesocket( SendSock );
		ErrorFlag = WSAGetLastError();
		printf("%d\n",ErrorFlag);
		if( Flag == SOCKET_ERROR ) printf("SendSock_CLOSE_ERROR");
	Flag = closesocket( RecvSock );
		ErrorFlag = WSAGetLastError();
		printf("%d\n",ErrorFlag);
		if( Flag == SOCKET_ERROR ) printf("RecvSock_CLOSE_ERROR");

	WSACleanup();
		ErrorFlag = WSAGetLastError();
		printf("%d\n",ErrorFlag);

	return 0;
}
Hello0のみかHello0~4全てのどちらかが必ず送信される

なので少しコードを変えて送信ごとにチェック

コード:

前略
	int len = sendto( SendSock, "HELLO-0", 7, 0, (struct sockaddr *)&ServerAddr, sizeof(ServerAddr) );
		ErrorFlag = WSAGetLastError();
		printf("%d\n",ErrorFlag);
		if( len == SOCKET_ERROR ) printf("SOCKET_ERROR");
		if( len < 7 ) printf("Short");
	len = sendto( SendSock, "HELLO-1", 7, 0, (struct sockaddr *)&ServerAddr, sizeof(ServerAddr) );
		ErrorFlag = WSAGetLastError();
		printf("%d\n",ErrorFlag);
		if( len == SOCKET_ERROR ) printf("SOCKET_ERROR");
		if( len < 7 ) printf("Short");
	len = sendto( SendSock, "HELLO-2", 7, 0, (struct sockaddr *)&ServerAddr, sizeof(ServerAddr) );
		ErrorFlag = WSAGetLastError();
		printf("%d\n",ErrorFlag);
		if( len == SOCKET_ERROR ) printf("SOCKET_ERROR");
		if( len < 7 ) printf("Short");
	len = sendto( SendSock, "HELLO-3", 7, 0, (struct sockaddr *)&ServerAddr, sizeof(ServerAddr) );
		ErrorFlag = WSAGetLastError();
		printf("%d\n",ErrorFlag);
		if( len == SOCKET_ERROR ) printf("SOCKET_ERROR");
		if( len < 7 ) printf("Short");
	len = sendto( SendSock, "HELLO-4", 7, 0, (struct sockaddr *)&ServerAddr, sizeof(ServerAddr) );
		ErrorFlag = WSAGetLastError();
		printf("%d\n",ErrorFlag);
		if( len == SOCKET_ERROR ) printf("SOCKET_ERROR");
		if( len < 7 ) printf("Short");
後略
毎回成功

このようになりました。
softya(ソフト屋) さんが書きました:あとServerAddrの内容をクリアしたらどうなります?
memset(&ServerAddr, 0x00, siezof(ServerAddr));
これはどこに入れたらいいんでしょう?

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: UDPデータ損失率

#51

投稿記事 by softya(ソフト屋) » 7年前

memset(&ServerAddr, 0x00, siezof(ServerAddr));は宣言の直後ですね。
なんか、今までの話を総合するとSleep(100)とか入れたら成功したりして。これまmemsetと別に実験して下さい。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

史上最悪のデスペナ
記事: 521
登録日時: 8年前

Re: UDPデータ損失率

#52

投稿記事 by 史上最悪のデスペナ » 7年前

エラーチェック、戻りチェック一切なし&memset
→完全成功率40%(4回/10回)、不完全成功率(Hello0のみ)10%(1回/10回)

エラーチェック、戻りチェック一切なし&memset無し&全Winsock関数後Sleep(100)
→100%(5回/5回)

中略

エラーチェック、戻りチェック一切なし&memset無し&全てのsendto後のみSleep(100)・・・・・・・・・・・・・・・A
→100%(10回/10回)

エラーチェック、戻りチェック一切なし&memset無し&一部のsendto後のみSleep(100)
→その後にSleepしなかったsendtoは送信されないことあり。
追記:Hello0に限ってはそれのみ送信されることもある

中略

Aの送信成功最低Sleep時間:1(ms)

結論:sendtoの後ある程度の時間を置かないとバッファ(?)が上書きされるなどの状況が発生し、送信が行われなくなることがある。

でも、そうするとMMOとかリアルタイム性の強いものはどうしたらいいのでしょう?
調べてみて、usleepやnanosleepというものを知りましたが、
このサイトの通り.hをインクルードしても関数定義が無いとエラーが出て使えません
最後に編集したユーザー 史上最悪のデスペナ on 2012年1月24日(火) 22:33 [ 編集 1 回目 ]

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: UDPデータ損失率

#53

投稿記事 by softya(ソフト屋) » 7年前

この事実から、私が予想するのはsendto()からclosesocket()の間にSleepが必要なのではないか?って事なのですが実験してもらえますか?ほかはSleepを外して下さい。

[追記]usleepやnanosleepはUnix/Linux用です。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

史上最悪のデスペナ
記事: 521
登録日時: 8年前

Re: UDPデータ損失率

#54

投稿記事 by 史上最悪のデスペナ » 7年前

softya(ソフト屋) さんが書きました:この事実から、私が予想するのはsendto()からclosesocket()の間にSleepが必要なのではないか?って事なのですが実験してもらえますか?ほかはSleepを外して下さい。
これも実験しました。
史上最悪のデスペナ さんが書きました:エラーチェック、戻りチェック一切なし&memset無し&一部のsendto後のみSleep(100)
→その後にSleepしなかったsendtoは送信されないことあり。
追記:Hello0に限ってはそれのみ送信されることもある
と同じ結果になりました。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: UDPデータ損失率

#55

投稿記事 by softya(ソフト屋) » 7年前

うーん。万策尽きました。
史上最悪のデスペナさんの状態が一般的な問題なのか広く普通にある状態なのか分からないのですが、Sleep(はごまかしに過ぎませんので最終最悪の手段でしかありません。
たまたま、上手く行っているように見えるだけかも知れません。

マイクロソフトの公式なサンプルは、この形ですのでこの形で上手くいかないのならOSやDLLやレジストリなどに何らかの異常があると判断したほうがよさそうです。
「sendto function」
http://msdn.microsoft.com/en-us/library ... s.85).aspx
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

beatle
記事: 1280
登録日時: 7年前
住所: 埼玉
連絡を取る:

Re: UDPデータ損失率

#56

投稿記事 by beatle » 7年前

的はずれな回答かもですが,同じ送信先にsendtoすると失敗する,みたいなことはないでしょうか.違う送信先なら連続でやっても成功するとか.
同じ送信先に連続でsendtoすることはあまり考慮されていないのかもって思ったんです.
同じ送信先に送るデータは一つの配列にまとめればいいだけの話ですからね.

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: UDPデータ損失率

#57

投稿記事 by softya(ソフト屋) » 7年前

beatleさんにもNo: 39 を試してもらいたいのですが、私の所では成功しますが史上最悪のデスペナさんの所では失敗する可能性のあるプログラムです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

beatle
記事: 1280
登録日時: 7年前
住所: 埼玉
連絡を取る:

Re: UDPデータ損失率

#58

投稿記事 by beatle » 7年前

No.27
softya(ソフト屋) さんが書きました: 「UDP/IPテストツールの詳細情報 : Vector ソフトを探す!」
http://www.vector.co.jp/soft/winnt/net/se478370.html
とNo.39
史上最悪のデスペナ さんが書きました: よろしくお願いします
01.zip
を組み合わせて,01.exe -> UDP/IPテストツールのテストを試みました.
まずUDP/IPテストツールで,ポート番号などいじらず,「接続」ボタンを押して接続しました.
次に,01.exeをターミナル上で実行したところ,UDP/IPテストツールのログ表示部分に
「->受 127.0.0.1 (49702)HELLO」
と表示されました.
bashスクリプトを利用し,連続で10回01.exeを実行したところ,ポート番号(49702)がインクリメントされる以外は初回と同様に受信されました.
「10回送信」を何度繰り返しても,その都度10回"HELLO"を受信します.

beatle
記事: 1280
登録日時: 7年前
住所: 埼玉
連絡を取る:

Re: UDPデータ損失率

#59

投稿記事 by beatle » 7年前

ちなみに私の環境は
Windows 7 Ultimate SP1 64bit
Intel Core i7 960 3.2GHz
6.0GB RAM
となっています.

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: UDPデータ損失率

#60

投稿記事 by softya(ソフト屋) » 7年前

ありがとうございます。
やはり環境問題なのかなって気がしてきました。

私は
Windows7 business sp1 64bit
AMD Athlon(tm) II X4 630 Processor 2.8GHz
メモリ 4GB
ウィルス対策ソフト:ウィルスバスター
ファイアウォール:Windowsファイアウォール
です。

【補足】他にもここを読んでいてテスト可能な方はテストをお願いします。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

閉鎖

“C言語何でも質問掲示板” へ戻る