今回winsockを使った通信プログラムを組む事になったのですが、わからない点が多々ありましたので、どなたかご教授頂けると大変ありがたいです。


1. TCP通信において、送信側が"Hoge" "Fuga"と2回sendした際、受信側でrecvすると"Ho" "geFu" "ga"と3回受信する可能性があると認識しているのですが、これは正しいでしょうか?
(到着する順序は保証されるが、recvする際に送信側がどのようにsendしたかは考慮されない)

2. UDP通信においては、上記のような現象は起きないと認識しているのですが、これは正しいでしょうか?
(UDP通信では、2回sendすれば2回以上はrecvしない。パケットの破棄はあっても、分割はない)

3. もしUDP通信でも上記のような現象が起きる場合、到着順序の保証がされないという観点から、recvした際に"Ho" "ga" "geFu"と受信する事はあり得るのでしょうか?

4. 2が正しい前提での話です。UDP通信では、MTUを超えた場合、自動でパケットが分割されると聞きました。プログラムを組む際、これは意識しないといけないのでしょうか?
(MTUが1500Byteの場合、UDPで2000Byteをsendすると、recvで1500,500と2回受信する?)


以上の4点です。
どなたかご存知の方いらっしゃいましたら、是非ご教授ください。

このQ&Aに関連する最新のQ&A

A 回答 (2件)

1.正しい


TCPはバイトストリームを送ります。バイト順は保障しますがパケットの単位は考慮されません。
2.概ね正しい
UDPはパケットを送ります。パケットを勝手に分割したり結合したりはしません。ただし同じパケットが複数回受信されることはあるので送信回数より多く受信する可能性は排除できません。
3.ない
ただしパケット単位での到着順は保障されません。
4.動作としては意識する必要はない
途中のIPパケットは分割されても、UDPで再構成した上で受信します。再構成できない場合はパケットの一部が受信されるのではなくパケット全体が破棄され受信されません。
ただし、上記により大きなパケットは届きにくいのでほとんどの場合にUDPは小さいサイズで送ります。そういう意味では意識する必要があります。
    • good
    • 0

>受信側でrecvすると"Ho" "geFu" "ga"と3回受信する可能性があると認識しているのですが、これは正しいでしょうか?



1回で受信する場合もあります。
http://www.kt.rim.or.jp/~ksk/wskfaq-ja/articles/ …

>(到着する順序は保証されるが、recvする際に送信側がどのようにsendしたかは考慮されない)

概ね合っている…かと。
# 順序だけでなく、通信エラーがあった場合の再送処理なども保証されます。
# ドライバが処理しているのでプログラム側では判りませんが。

>(UDP通信では、2回sendすれば2回以上はrecvしない。パケットの破棄はあっても、分割はない)

分割に関しては不明(UDP使ったことないので)ですが…
同じパケットを複数回受信することもある…らしいです。

>3. もしUDP通信でも上記のような現象が起きる場合、到着順序の保証がされないという観点から、recvした際に"Ho" "ga" "geFu"と受信する事はあり得るのでしょうか?

ありえる。
と考えておいたほうがよい…かと。

>UDP通信では、MTUを超えた場合、自動でパケットが分割されると聞きました。プログラムを組む際、これは意識しないといけないのでしょうか?

意識すべし…なのかも知れませんが…。
下層でのデータフレームのサイズに関して、どこまで考慮すべきなのか…は不明です。
PPPの場合もあったりするでしょうし。

http://www.kt.rim.or.jp/~ksk/wskfaq-ja/intermedi …
とりあえず、よろしく処理してくれる…らしいです。
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QC言語のゲームのサンプルプログラムが置いてあって自由に修正できるサイト教えてもらえないでしょうか?

ゲームのサンプルプログラムが置いてあって自由に修正できるサイト教えてもらえないでしょうか?

Aベストアンサー

C言語、自体があまり初心者向けではないのですが、
Cを本気で学ぼうと考えるなら、書籍を購入する事をお勧めします。

「C言語〈1〉はじめてのCプログラミング プログラミング学習シリーズ」
倉 薫 (著)
アマゾン(http://www.amazon.co.jp/)の古本で400円で販売していました。
私が昔、他の人にC言語を教えるときに使った教材ですが非常に簡単でした。
「簡単」というのがポイントで初めてCを学ぶ方から非常に読みやすいと定評があった本です。

ただこれを読んだからといってすぐに市販されているようなゲームが作れるわけではありません。
C言語でゲームを作るのはかなり地道ですし下地になる知識が相当必要です。

とりあえず市販のコンパイラ(コンパイラというのはexe等を作るやつ)は
必要になってから買うので十分です。
先に説明した無償のコンパイラで市販レベルのソフトを作る事も可能なのです。
(市販のものと何が違うかというとマニュアル、ツール、ライブラリ等が付属している点)
やろうと思えばそのツールやライブラリもその無償のコンパイラで作れるわけですから。

また前回とかぶりますが
http://www.kumei.ne.jp/c_lang/bcc/index.html
でBCCというコンパイラをインストールし
http://www.kumei.ne.jp/c_lang/index_c.html
の1章から見ていって実際もexeにして実行してみてください。
このサイトも参考になります。

C言語、自体があまり初心者向けではないのですが、
Cを本気で学ぼうと考えるなら、書籍を購入する事をお勧めします。

「C言語〈1〉はじめてのCプログラミング プログラミング学習シリーズ」
倉 薫 (著)
アマゾン(http://www.amazon.co.jp/)の古本で400円で販売していました。
私が昔、他の人にC言語を教えるときに使った教材ですが非常に簡単でした。
「簡単」というのがポイントで初めてCを学ぶ方から非常に読みやすいと定評があった本です。

ただこれを読んだからといってすぐに市販されている...続きを読む

Qwinsockを使ったネットワークプログラミングについて。 Winsockを使用したプログラムに悪戦

winsockを使ったネットワークプログラミングについて。
Winsockを使用したプログラムに悪戦苦闘中なんですが、送信用関数にsend,sendto、受信用関数にrecover,recvfromがありますよね。ネット等で調べた結果「TCPではsendとrecv,UDPではsendtoとrecvfromを主に使う」との記載を目にしました。
では例えばですが、パソコンA,Bがあったとして、TCP設定のソケットを使いAからBへsend関数でデータ送信、Bはrecvfromでデータを受信かつrecvfrom第五引数のデータを使いAのIPアドレスを取得。ということは可能でしょうか?

Aベストアンサー

一般的な回答として、そのようなことはできません。 (厳密な話しをすればパケットキャプチャーなどの技術を使えば可能ですが...)
そもそも、TCP/IPとUDP/IPではプロトコルが違います。 TCP/IPでは「接続」手順が必要で、この手順を無しにUDP/IPのように送信することはできません。
相手のIPアドレスを知りたいだけならTCP/IPでAからBへ「接続」した時点で、BはAのIPアドレスを知ることができます。

QC言語・ゲーム作成で挫折気味の対処方法

こんばんは。ゲーム作成に関わらず、C言語で挫折気味の時、みなさんはどのように対処してきましたか?
以下、私の現在の状況を説明致します。

C言語でゲームを作成するという目的でC言語を勉強し、ゲーム作成の勉強をしていました。
C言語の書籍を一通り行い、DXライブラリを使用して、それに関するサイト(ゲームプログラミングの館等)を参考にしながらゲーム作成の勉強をしていました。
しかし、除々に分からなくなり、手がつけられなくなってしまいました。
ゲームを早く作成してみたいという気持ちが先走り、C言語の知恵が足りない(勉強期間:1ヶ月程度)のに
ゲーム作成に取り掛かろうとしたことがが原因のひとつだと思い、もう一度、C言語を勉強し直そうと考えています。
しかし、数ある書籍やサイトの中でどれがゲームプログラミングを学ぶのに適しているの分かりません。
みなさんがゲームプログラミングをするにあたって利用した書籍やサイトはどのようなものでしょうか?
また、同じようにC言語でゲームを作成している方にお聞きしたいのですが、C言語をどの程度勉強されてからゲーム作成に取り掛かったのでしょうか?

みなさんの意見を参考にして、勉強していきたいので、よろしければアドバイスをお願い致します。

こんばんは。ゲーム作成に関わらず、C言語で挫折気味の時、みなさんはどのように対処してきましたか?
以下、私の現在の状況を説明致します。

C言語でゲームを作成するという目的でC言語を勉強し、ゲーム作成の勉強をしていました。
C言語の書籍を一通り行い、DXライブラリを使用して、それに関するサイト(ゲームプログラミングの館等)を参考にしながらゲーム作成の勉強をしていました。
しかし、除々に分からなくなり、手がつけられなくなってしまいました。
ゲームを早く作成してみたいという気持ちが先...続きを読む

Aベストアンサー

私は、最初の頃は「SDL」を使って2Dゲームを作っていました。
その頃は、C言語は関数もあまり分かっていませんでした。
ですけど、勉強し直して「OpenGL」で3Dの簡単な動きなら動かせるようになりました。
今は作っていませんけど。

私が勉強に使った本を紹介します。
C言語の本
「図解C言語 ポインタの極意」
「新版 明解C言語 入門編」

C++言語の本
憂鬱なプログラマのためのオブジェクト指向開発講座

どのくらいC言語を理解しているか分かりませんけど、
分からないものが多く載っていて分かりやすい本を立ち読みをして、
探した方がいいと思います。

ゲームは2Dでしょうか?
それとも、3Dでしょうか?
3Dでしたら物理などが分からないと無理です。
物理の本(プログラムも載っています)
「ゲーム開発のための物理シミュレーション入門」

C++言語が分かれば、
「ゲームプログラマになる前に覚えておきたい技術」
がいいらしいです。

QWinSockを用いたUDP送受信ソケットプログラミングについて

こんにちは。
現在、VC++.NETでWinSockを用いたUDPソケットプログラミングを行っています。以下のようなプログラムを作りたいと思っているのですがうまく動作しません。

[概要]
A:送信端末
B:受信端末

1.Aから文字列"send"をB端末へ送信。
2."send"を受信した受信端末Bは、A端末へ文字列"ok"を送信。

この1と2の動作を行わせたいと思っています。この場合、A,B端末は送信と受信を行う必要があります。

[問題点(うまくいかない点)]
A→Bへ"send"は送信でき、B端末で受信できるのですが、B端末からA端末へ送信できません。B端末で送信できているのか、それともA端末で受信できていないのか?が分からない状態です。

[気づいた点]
ポート番号を分ける必要があるのでしょうか?例えば、A→Bへは9000番。B→Aへは9001番という意味です。

送信と受信を行うため、送信・受信で2つのUDPソケットを使用する必要があるのでしょうか?例えば、
s1 = socket(AF_INET, SOCK_DGRAM, 0);←送信に利用
s2 = socket(AF_INET, SOCK_DGRAM, 0);←受信に利用

よろしくお願いします。

こんにちは。
現在、VC++.NETでWinSockを用いたUDPソケットプログラミングを行っています。以下のようなプログラムを作りたいと思っているのですがうまく動作しません。

[概要]
A:送信端末
B:受信端末

1.Aから文字列"send"をB端末へ送信。
2."send"を受信した受信端末Bは、A端末へ文字列"ok"を送信。

この1と2の動作を行わせたいと思っています。この場合、A,B端末は送信と受信を行う必要があります。

[問題点(うまくいかない点)]
A→Bへ"send"は送信でき、B端末で受信できるのですが、B...続きを読む

Aベストアンサー

>B端末で送信できているのか、それともA端末で受信できていないのか?
可能であればEtherRealというパケットキャプチャのインストールをおすすめします。デバッグが楽です。

>ポート番号を分ける必要があるのでしょうか?
たぶん大丈夫だと思います。
A->B の場合、Aがsendtoで指定するのは送信元ポートではなく、送信先ポートです。
それがBのソケットの受信ポートと一致してさえいればよいです。
EtherRealでモニタしていると、送信元ポートはどうやら適当に決まっているようです。

>送信と受信を行うため、送信・受信で2つのUDPソケットを使用する必要があるのでしょうか?
非ブロッキングモードでの送受信(WSAASyncSelect等を使う)の場合は、FD_READ | FD_WRITE とすれば取りこぼしなく送受信できそうな気がします。
ブロッキングモードのときはだめかもしれないです。

QC言語でプログラムを再起動

 UNIXで動くC言語のプログラムを作っています。
 その際、プログラムを再起動させたい時があります。
 しかし、C言語でプログラムを再起動させるってどうやればいいのかよくわかりません。
 何かよいやり方を知っている方、教えてください。
 よろしくお願いします。

Aベストアンサー

関数execl()を使えばよいと思います。
この関数は、fork()と組み合わせて、他のプログラムを
起動するのに使うのが普通ですが、
fork()せずにexecl()を呼ぶと、自プロセスを指定された
プログラムに置き換えます。ですので、ここで自分自身を
指定すれば、再起動したことになるはずです。

Qwinsockを使った通信方法

送信側
#include <winsock2.h>
#include <string.h>
int
main()
{
WSAData wsaData;

SOCKET sock;
struct sockaddr_in addr;
int len;
typedef struct recv {
char Name[32];
int Flag;
} RECV;

RECV send;

WSAStartup(MAKEWORD(2,0), &wsaData);

sock = socket(AF_INET, SOCK_DGRAM, 0);

addr.sin_family = AF_INET;
addr.sin_port = htons(12345);
addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");

strcat(send.Name, "ABC");
send.Flag=12;
len=sizeof(send);
sendto(sock,(char *)&send,len, 0, (struct sockaddr *)&addr, sizeof(addr));

closesocket(sock);

WSACleanup();

system("pause");

return 0;
}

受信側


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

int
main()
{
typedef struct rcv {
char Name[32];
int Flag;
} RECV;
WSAData wsaData;

SOCKET sock;
struct sockaddr_in addr;

int len;

RECV rcv;

WSAStartup(MAKEWORD(2,0), &wsaData);

sock = socket(AF_INET, SOCK_DGRAM, 0);

addr.sin_family = AF_INET;
addr.sin_port = htons(12345);
addr.sin_addr.S_un.S_addr = INADDR_ANY;

bind(sock, (struct sockaddr *)&addr, sizeof(addr));

len=sizeof(rcv);
recv(sock,(char *)&rcv, len, 0);

printf("%s [%d]\n",rcv.Name,rcv.Flag);

closesocket(sock);

WSACleanup();

system("pause");

return 0;
}

winsockを使ったUDP通信プログラムで構造体データを送る事が出来ないのですが
どこに誤りがあるのでしょうか?
コンパイルは通ってるのですが、送信側を起動しても受信側で受け取ることが出来ていない状況です。

送信側
#include <winsock2.h>
#include <string.h>
int
main()
{
WSAData wsaData;

SOCKET sock;
struct sockaddr_in addr;
int len;
typedef struct recv {
char Name[32];
int Flag;
} RECV;

RECV send;

WSAStartup(MAKEWORD(2,0), &wsaData);

sock = socket(AF_INET, SOCK_DGRAM, 0);

addr.sin_family = AF_INET;
addr.sin_port = htons(12345);
addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");

strcat(send.Name, "ABC");
send.Flag=12;
len=sizeof(send);
sendto(sock,(char *...続きを読む

Aベストアンサー

>ちゃんと初期化しなかったのが原因であってますか?

原因の一つではありますが、それが全てではありません。
大本の原因は不適切な関数の使用でしょう。

>strcat(send.Name, "ABC");

strcat()ではなくstrcpy()を使うべきではありませんか?

上から順にコードを読んだ人は、ここでstrcat()を使用することに違和感を覚えるでしょう。

連結ってことはここより前になにか文字列を設定しているハズ。
ということはコードの見落としがあったのか?確かめないと。
見落としはなかった、文字列の設定もされていないのになんで連結なんだろう?
define定義で関数コールが隠蔽されていたのかも知れない。そっちも確認しないと。

などなど。

QC言語でゲーム作り

フリーゲームに影響され、自分も作ってみたいと思いC言語勉強し始めました
趣味の範囲で、こつこつ頑張っていこうと思ってます

今現在、C言語の初初心者向けの本を一通り読み終えて次の本を読んでます
一応、一つの目標としてアクションゲーム(マリオみたいな)を作りたいんですが
C言語の他にどんなこと勉強すればいいでしょうか?

あと、C言語から次のステップに移るときは
やはり上級者向けの本は理解できるくらいまで頑張ってからでしょうか?

Aベストアンサー

とりあえずCだけではなく、C++まで一通り学習することをお勧めします。
PCゲームなのかどうか、Windows上のものなのかどうかわかりませんが、C/C++系の場合は、C++使っていることが多いので、C++知っているのと知らないのとでは、サンプルだとかライブラリとか理解できないかもしれないので。

仮にWindowsアプリだとして、API叩いてGDIで描画するか、DirectXを使うかというところもありますね。
2Dの横スクロールならGDIでも可能でしょうけど、後々のことを考えるとDirectX使えるように勉強したほうが、楽だしいろいろなことができるようになります。
DirectXはC++なので、やはりC++になります。

ちょっと戻ってしまいますが、Windowsアプリを作るのであれば、CやC++言語だけではだめで、WindowsAPIを使う必要があります。
まぁ一種のライブラリだと思えばよいですけど。

とりあえず、C/C++の入門書を一通りみて、どのような文法や制約などがあるか理解し(覚えなくてOK)、実際のサンプルソースなどをいじったり改良したりして実際の動作を見ていくのがよろしいかと。
コンソールでのC/C++がある程度わかってきたら、WindowsAPIやDirectXなどの入門書を見ていくといいのではないかとおもいます

とりあえずCだけではなく、C++まで一通り学習することをお勧めします。
PCゲームなのかどうか、Windows上のものなのかどうかわかりませんが、C/C++系の場合は、C++使っていることが多いので、C++知っているのと知らないのとでは、サンプルだとかライブラリとか理解できないかもしれないので。

仮にWindowsアプリだとして、API叩いてGDIで描画するか、DirectXを使うかというところもありますね。
2Dの横スクロールならGDIでも可能でしょうけど、後々のことを考えるとDirectX使えるように勉強したほうが、楽だ...続きを読む

QTCP/IP通信型大文字・小文字変換プログラム

TCP/IP通信型大文字・小文字変換プログラムを作りたいです。
しかし、うまく2つのプログラムが接続されません。
恐らく、IPアドレスやホスト名の問題だと思います。
超初心者でそこのところをあまり理解していません。
どなたかプログラムの補足をお願いします。

概要は
・クライアント
キーボードから文字列を入力し、サーバーに送信。
サーバーから送信された文字列を画面に出力。

・サーバー
クライアントから送信された文字列に対し、
大文字は小文字に、小文字は大文字に変換して返す。

クライアント側プログラム

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>

#define SOCK_NAME "./socket"

int main()
{
struct sockaddr_in saddr;
int soc;
char buf[1024];

if ( (soc =socket(AF_INET, SOCK_STREAM, 0 ) ) < 0 ) {
perror("socket");
exit(1);
}

memset((char *)&saddr, 0, sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr=inet_addr("192.168.1.1");
saddr.sin_port=htons(1357);

if(connect(soc, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) {
perror("connect");
exit(1);
}
fprintf(stderr, "Connection established: socket %d used.\n", soc);

while(fgets(buf, 1024, stdin)){
if(buf[strlen(buf) -1] == "\n") buf[strlen(buf) -1] = "\0";
write(soc, buf, 1024);
read(soc, buf, 1024);
fprintf(stdout, "%s\n", buf);
}
close(soc);
return 0;

}

サーバー側プログラム

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#define SOCK_NAME "./socket"

int main()
{
int i;
int fd1, fd2;
struct sockaddr_in saddr;
struct sockaddr_in caddr;

int len;
int ret;
char buf[1024];

if((fd1 =socket(AF_INET, SOCK_STREAM, 0)) < 0 ){
perror("socket");
exit(1);
}

memset((char *)&saddr, 0, sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr=INADDR_ANY;
saddr.sin_port=htons(1357);


unlink(SOCK_NAME);
if(bind(fd1, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) {
perror("bind");
exit(1);
}
if(listen(fd1,5) < 0 ) {
perror("listen");
exit(1);
}
while(1){
len = sizeof(caddr);
if((fd2 = accept(fd1, (struct sockaddr *)&caddr, &len)) < 0){
perror("accept");
exit(1);
}

fprintf(stderr, "Connection established: socket %d used.\n", fd2);

while((ret = read(fd2, buf, 1024)) > 0 ){
fprintf(stderr, "read: &s\n", buf);
for(i=0; i<ret; i++)
if(islower(buf[i]))
buf[i] = toupper(buf[i]);
if(isupper(buf[i]))
buf[i] = tolower(buf[i]);

fprintf(stderr, "write: %s\n", buf);
write(fd2, buf, 1024);
}
close(fd2);
}
close(fd1);

return 0;
}

TCP/IP通信型大文字・小文字変換プログラムを作りたいです。
しかし、うまく2つのプログラムが接続されません。
恐らく、IPアドレスやホスト名の問題だと思います。
超初心者でそこのところをあまり理解していません。
どなたかプログラムの補足をお願いします。

概要は
・クライアント
キーボードから文字列を入力し、サーバーに送信。
サーバーから送信された文字列を画面に出力。

・サーバー
クライアントから送信された文字列に対し、
大文字は小文字に、小文字は大文字に変換して返す。

...続きを読む

Aベストアンサー

クライアント側でIPアドレスとして 192.168.1.1を指定していますけど
これはあってますか?

プログラムにバグがあったので、それを修正した上で
ループバックアドレス(127.0.0.1)を指定して試したところ
うまく動作しました。

いきなりサーバーとクライアント両方を試すより、
サーバーは正しく動くのか、
クライアントは正しく動くのか
をそれぞれ試すようにした方がよくはないですか。

サーバーのテストなら telnetでも試せますし。

QC言語のプログラム集

こんにちは。C言語のテキストにはプログラムとその説明が書いていますが、
このC言語のプログラムが多くのっているような本はありますか?本屋さんで探したのですが、プログラムがものすごく多くのっているようなものがなかったので、もしお分かりの方がおられましたが、本の紹介をお願いします。

Aベストアンサー

C言語ということでどうしても古い本になってしまいますが
下記URLのような本はどうでしょうか。
http://oku.edu.mie-u.ac.jp/~okumura/algo/
http://www.amazon.co.jp/%E3%83%8B%E3%83%A5%E3%83%BC%E3%83%A1%E3%83%AA%E3%82%AB%E3%83%AB%E3%83%AC%E3%82%B7%E3%83%94%E3%83%BB%E3%82%A4%E3%83%B3%E3%83%BB%E3%82%B7%E3%83%BC-%E6%97%A5%E6%9C%AC%E8%AA%9E%E7%89%88%E2%80%95C%E8%A8%80%E8%AA%9E%E3%81%AB%E3%82%88%E3%82%8B%E6%95%B0%E5%80%A4%E8%A8%88%E7%AE%97%E3%81%AE%E3%83%AC%E3%82%B7%E3%83%94-William-H-Press/dp/4874085601

ご参考になれば幸いです。

QTCP/IP通信型プログラムです。作成するのはクライアントです。たとえ

TCP/IP通信型プログラムです。作成するのはクライアントです。たとえば、サーバから入力を求められ、それが正しくあれば、次の状態へ。正しくなければ、状態を遷移させなかったり。そして、状態が遷移したということをサーバに伝えなければなりません。自分としては、条件式などを利用しようかと思っているのですが・・・。(状態遷移図の作成ではありません。)
ほんのわずかなヒントでもいいので、お助け願います。

Aベストアンサー

前回も書きましたが質問したい内容が何なのか分かりません

これだと じゃあ自分で書いてあることやれば? ってことになりますが
そういうのを期待してるわけではないんですよね?


人気Q&Aランキング

おすすめ情報