質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.44%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

ソケット

TCP/IPにおいて、IPアドレスとサブアドレスであるポート番号を組み合わせたネットワークアドレスのことを呼びます。また、ソフトウェアアプリケーションにおいて、TCP/IP通信を行う為の仮想的なインターフェースという意味もある。

TCP

TCP(Transmission Control Protocol)とは、トランスポート層のプロトコルで、コネクション型のデータサービスです。

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

7088閲覧

ソケット通信(Winsock2)のソケットの再利用について

jmsn

総合スコア12

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

ソケット

TCP/IPにおいて、IPアドレスとサブアドレスであるポート番号を組み合わせたネットワークアドレスのことを呼びます。また、ソフトウェアアプリケーションにおいて、TCP/IP通信を行う為の仮想的なインターフェースという意味もある。

TCP

TCP(Transmission Control Protocol)とは、トランスポート層のプロトコルで、コネクション型のデータサービスです。

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/08/30 00:43

お世話になります.現在Winsock2を用いて,サーバに接続→送受信→別の処理→同じサーバに接続→...といった処理のクライアントプログラムを作成しておりますが,下記のコードですと再接続時に10056のエラーが生じてしまします.

c

1WSAStartup(MAKEWORD(2,0), &wsaData); 2sock = socket(AF_INET, SOCK_STREAM, 0); 3connect(sock,(sockaddr *)&server,sizeof(server)); 4/*送受信*/ 5/*別の処理*/ 6connect(sock,(sockaddr *)&server,sizeof(server));//Error:10056 7/*送受信*/ 8/*別の処理*/ 9closesocket(sock); 10WSACleanup();

一方,1回の接続ごとにソケットの作成/クローズをおこなう下記のプログラムですと,エラーなく冒頭の処理を実現できますが,同じ設定のソケットを何度も作成するのは冗長に感じます.

c

1WSAStartup(MAKEWORD(2,0), &wsaData); 2sock = socket(AF_INET, SOCK_STREAM, 0); 3connect(sock,(sockaddr *)&server,sizeof(server)); 4/*送受信*/ 5/*別の処理*/ 6closesocket(sock); 7 8sock = socket(AF_INET, SOCK_STREAM, 0); 9connect(sock,(sockaddr *)&server,sizeof(server)); 10/*送受信*/ 11/*別の処理*/ 12closesocket(sock); 13WSACleanup();

冒頭の処理を実現するのにより良い方法などがありましたらお教えいただければ幸いです.

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ソケット(クライアントとサーバの間の通信経路)は、クライアントの"IPアドレスとポート番号"と、サーバの"IPアドレスとポート番号"のペアで識別されます。

connectの際には、以下のような動作が起こります。
0) クライアントでソケットを生成すると、使用中でないポート番号の一つ(ここでは、11111とします)が割り振られます。
1) クライアントから、サーバの待ち受け(listen)ポート(例えば、80)に対して接続を要求します。
2) サーバは、使用中ではないポート番号の一つ(ここでは、22222とします)を割り当てて、その情報をクライアント側に返す。
3) クライアントは、サーバからの応答で「クライアントの"ポート番号11111"と、サーバの"ポート番号22222"の間の通信路が出来た(接続された)」ことが判ります

この状態で、クライアントのポート番号11111を持つソケットで、サーバの80番ポートに接続要求をした、というのが質問にある"再接続"(質問のプログラムの2つ目のconnect)です。

クライアントのポート番号11111は、既にサーバのポート番号22222と接続済みですから、他と接続することが出来ません。

そこで、「10056 ソケットは既に接続されています」というエラーになったのです。

まぁ、電話で通話中に電話番号をプッシュしても、その番号にはつながらないのと同じような感じです。

==
これを解決するには、2つ目のプログラムのようにコネクションの作成・クローズを繰り返すしかありません。

投稿2020/08/30 03:53

coco_bauer

総合スコア6915

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jmsn

2020/09/02 02:54

やはり2つ目のプログラムの方法を繰り返す必要があるのですね. ご回答ありがとうございます.
guest

0

ベストアンサー

closesocketしてからconnectしてみたらどうなるでしょう

#そりゃconnect済のソケットをそのままconnectしようとしたらエラーになるでしょ

投稿2020/08/30 00:51

y_waiwai

総合スコア87849

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jmsn

2020/08/30 01:04

ご回答ありがとうございます.下記コードを試したところ,10038のエラーが生じました. WSAStartup(MAKEWORD(2,0), &wsaData); sock = socket(AF_INET, SOCK_STREAM, 0); connect(sock,(sockaddr *)&server,sizeof(server)); /*送受信,別の処理*/ closesocket(sock); connect(sock,(sockaddr *)&server,sizeof(server));//Error:10038 /*送受信,別の処理*/ closesocket(sock); WSACleanup();
dodox86

2020/08/30 01:14

> 10038のエラーが生じました. 10038は WSAENOTSOCK を示しているので、ソケットがもはや無効です。 https://docs.microsoft.com/en-us/windows/win32/winsock/windows-sockets-error-codes-2 closesocket()はsocket()で作成したソケットに対するcloseなので、ソケット自体が閉じられ、使えなくなります。 https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-closesocket > An application should always have a matching call to closesocket for each successful call to socket to return any socket resources to the system.
jmsn

2020/08/30 01:20

ご返信ありがとうございます.やはり,1回の接続ごとにソケットの作成/クローズをおこなう処理しかないのでしょうか.
dodox86

2020/08/30 01:36

> 1回の接続ごとにソケットの作成/クローズをおこなう処理しかないのでしょうか. 基本、そうです。私自身は「TCPのクライアント/サーバー通信はそういうものだ」と理解していたので質問者さんのように特に冗長に感じてはいず、質問者さんの疑問に応える内容の回答を持たなかったので回答しませんでした。サーバー側の動作次第ですが、サーバー側から切断しないのであれば送受信したあとの別の処理の後、またsend/recvすれば良いのではないでしょうか。送受信したからと言ってすぐ切断しなければいけないものではないです。サーバーにリクエスト送信、サーバー側からレスポンス受信で必ず切断する必要があるなら、socket()で作成~closesocket()でクローズしなければダメです。そういうものです。
jmsn

2020/08/30 01:49

ご回答ありがとうございます. 大変勉強になります,抱えていた疑問が解決いたしました.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.44%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問