WinSockの勉強をしています。

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
きよし

WinSockの勉強をしています。

#1

投稿記事 by きよし » 11年前

Winsockを使ってサーバー、クライアントの勉強をしています。
自分のパソコンをプロキシサーバーのようにしてみようかと思って作っていたのですが、
どうしてもわからないので教えてください。

コード:

#include <stdio.h>
#include <winsock2.h>
#include "BREGEXP.H"

#pragma comment(lib,"wsock32.lib")
#pragma comment(lib,"BREGEXP.LIB")

void _tcp_client(char *,char *);

int main()
{
	WSADATA wsaData;
	SOCKET sock0;
	struct sockaddr_in addr;
	struct sockaddr_in client;
	int len;
	SOCKET sock;
	BOOL yes = 1;

	char inbuf[20480];

	char *buf_data = "\0";
	char out[20480];

	int client_flag = 0;

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

	sock0 = socket(AF_INET, SOCK_STREAM, 0);
	
	if(sock0 == INVALID_SOCKET)
	{
		printf("socket : %d\n", WSAGetLastError());
		return 1;
	}

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

	setsockopt(sock0,SOL_SOCKET, SO_REUSEADDR, (const char *)&yes, sizeof(yes));

	if(bind(sock0, (struct sockaddr *)&addr, sizeof(addr)) != 0)
	{
		printf("bind : %d\n", WSAGetLastError());
		return 1;
	}

	if(listen(sock0, 5) != 0)
	{
		printf("listen : %d\n", WSAGetLastError());
		return 1;
	}

	while(1)
	{
		len = sizeof(client);
		sock = accept(sock0, (struct sockaddr *)&client, &len);

		if(sock == INVALID_SOCKET)
		{
			printf("accept : %d\n", WSAGetLastError());
			break;
		}

		memset(inbuf, 0, sizeof(inbuf));
		recv(sock, inbuf, sizeof(inbuf), 0);

		memset(out, 0, sizeof(out));
		_tcp_client(inbuf,out);

		printf("%s\n"
		       "-------------------------------------\n",out);

		send(sock,out,(int)strlen(out),0);

		closesocket(sock);
	}

	WSACleanup();

	return 0;
}

void _tcp_client(char *buf,char *out_buf)
{
	WSADATA wsaData;
	SOCKET sock;
	char r_buf[20480];
	unsigned int **addrptr;
	struct sockaddr_in server;
	struct hostent *host;
	int n;

	BREGEXP *rxp = NULL;

	char msg[80];
	char patern1[] = "m/Host: (.*)/i";
	int pos = 0;
	int i = 0;
	char server_host[1024];

	//////////////////////////////////////////////////
	//                                              //
	//          接続先Hostの取得(正規表現)          //
	//                                              //
	//////////////////////////////////////////////////

	while(BMatch(patern1,buf+pos,buf+strlen(buf),&rxp,msg))
	{
		//printf("data=%s\n",buf+pos);
		//printf("found=%s\n",rxp->startp[0]);
		//printf("length=%d\n",rxp->endp[0] - rxp->startp[0]);

		for(i=1; i<=rxp->nparens; i++)
		{
			//printf("%d = %s\n",i,rxp->startp[i]);
		}

		pos = rxp->endp[0] - buf;
	}

	for(i=0; i<(rxp->endp[1] - rxp->startp[1]); i++)
	{
		server_host[i] = rxp->startp[1][i];
	}

	i += 1;
	server_host[i] = '\0';

	//////////////////////////////////////////////////
	//                                              //
	//          サーバー接続(ソケット開始)          //
	//                                              //
	//////////////////////////////////////////////////

	if(WSAStartup(MAKEWORD(2,0),&wsaData) != 0)
	{
		printf("ERROR 0001");
		return;
	}

	sock =socket(AF_INET,SOCK_STREAM,0);

	if(sock == INVALID_SOCKET)
	{
		printf("ERROR 0002");
		return;
	}

	server.sin_family = AF_INET;
	server.sin_port = htons(80);
	server.sin_addr.S_un.S_addr = inet_addr(server_host);

	host = gethostbyname(server_host);

	if(host == NULL)
	{
		if(WSAGetLastError() == WSAHOST_NOT_FOUND)
		{
			printf("ERROR 0003");
			return;
		}

		printf("ERROR 0004");
		return;
	}

	addrptr = (unsigned int **)host->h_addr_list;

	server.sin_addr.S_un.S_addr = *(*addrptr);

	if(connect(sock,(struct sockaddr *)&server,sizeof(server)) == -1)
	{
		printf("ERROR code to 0005");
		return;
	}

	printf("%s\n"
	       "-------------------------------------\n",buf);

	n = send(sock,buf,(int)strlen(buf),0);

	while(n > 0)
	{
		memset(r_buf,0,sizeof(r_buf));

		n = recv(sock,r_buf,sizeof(r_buf),0);
	}

	strcpy(out_buf,r_buf);

	closesocket(sock);

	WSACleanup();
}

iPhoneのWiFi設定のところからプロキシを設定し、自分のパソコンを経由してインターネットを閲覧しようと思っています。
簡易的なパケットモニターもできると思い、サーバー、クライアントの勉強を兼ねて作成しようとしています。
上記コードのERROR 0004のところで止まってしまいます。
Hostは取得できているのですが、何が問題でしょう?

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: WinSockの勉強をしています。

#2

投稿記事 by みけCAT » 11年前

どのようなエラーが起きているか、WSAGetLastError()とFormatMessage()で確認しましたか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

きよし

Re: WinSockの勉強をしています。

#3

投稿記事 by きよし » 11年前

みけCAT さんが書きました:どのようなエラーが起きているか、WSAGetLastError()とFormatMessage()で確認しましたか?
WSAGetLastError()で確認したところ11004が出ました。
この意味がよくわからないのですが。。。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: WinSockの勉強をしています。

#4

投稿記事 by みけCAT » 11年前

WSANO_DATA (11004)

意味 : 要求された名前は有効ですが、要求された種類のデータ レコードがありません。
説明 : 要求された名前は有効で、データベースに存在しますが、解決先の正しい関連データが存在しません。一般的な例として、DNS サーバーを使用してホスト名をアドレスに変換しようとした場合 (gethostbyname (Wsapiref_0q5u.asp) または WSAAsyncGetHostByName (Wsapiref_7bhu.asp) を使用) に発生することがあります。MX レコードは返されますが、A レコードは返されません。これはホスト自体は存在するが、直接到達できないことを示しています。
(http://support.microsoft.com/kb/819124/ja)

なぜでしょうか…
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

きよし

Re: WinSockの勉強をしています。

#5

投稿記事 by きよし » 11年前

うーん。。。
全然わからないのですが、なぜAレコードが返らないのでしょうか?

私のソースに問題ありますかね?

きよし

Re: WinSockの勉強をしています。

#6

投稿記事 by きよし » 11年前

ソースコードをちょっと変更しました。

コード:

#include <stdio.h>
#include <winsock2.h>
#include "BREGEXP.H"

#pragma comment(lib,"wsock32.lib")
#pragma comment(lib,"BREGEXP.LIB")

void _tcp_client(char *,char *);

int main()
{
	WSADATA wsaData;
	SOCKET sock0;
	struct sockaddr_in addr;
	struct sockaddr_in client;
	int len;
	SOCKET sock;
	BOOL yes = 1;

	char inbuf[20480];

	char *buf_data = "\0";
	char out[20480];

	int client_flag = 0;

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

	sock0 = socket(AF_INET, SOCK_STREAM, 0);
	
	if(sock0 == INVALID_SOCKET)
	{
		printf("socket : %d\n", WSAGetLastError());
		return 1;
	}

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

	setsockopt(sock0,SOL_SOCKET, SO_REUSEADDR, (const char *)&yes, sizeof(yes));

	if(bind(sock0, (struct sockaddr *)&addr, sizeof(addr)) != 0)
	{
		printf("bind : %d\n", WSAGetLastError());
		return 1;
	}

	if(listen(sock0, 5) != 0)
	{
		printf("listen : %d\n", WSAGetLastError());
		return 1;
	}

	while(1)
	{
		len = sizeof(client);
		sock = accept(sock0, (struct sockaddr *)&client, &len);

		if(sock == INVALID_SOCKET)
		{
			printf("accept : %d\n", WSAGetLastError());
			break;
		}

		memset(inbuf, 0, sizeof(inbuf));
		recv(sock, inbuf, sizeof(inbuf), 0);

		memset(out, 0, sizeof(out));
		_tcp_client(inbuf,out);

		printf("%s\n"
		       "-------------------------------------\n",out);

		send(sock,out,(int)strlen(out),0);

		closesocket(sock);
	}

	WSACleanup();

	return 0;
}

void _tcp_client(char *buf,char *out_buf)
{
	WSADATA wsaData;
	SOCKET sock;
	char r_buf[20480];
	unsigned int **addrptr;
	struct sockaddr_in server;
	struct hostent *host;
	int n;

	BREGEXP *rxp = NULL;

	char msg[80];
	char patern1[] = "m/Host: (.*)/i";
	int pos = 0;
	int i = 0;
	char server_host[1024];

	printf("%s\n\n",buf);

	//////////////////////////////////////////////////
	//                                              //
	//          接続先Hostの取得(正規表現)          //
	//                                              //
	//////////////////////////////////////////////////

	while(BMatch(patern1,buf+pos,buf+strlen(buf),&rxp,msg))
	{
		//printf("data=%s\n",buf+pos);
		//printf("found=%s\n",rxp->startp[0]);
		//printf("length=%d\n",rxp->endp[0] - rxp->startp[0]);

		for(i=1; i<=rxp->nparens; i++)
		{
			//printf("%d = %s\n",i,rxp->startp[i]);
		}

		pos = rxp->endp[0] - buf;
	}

	for(i=0; i<(rxp->endp[1] - rxp->startp[1]); i++)
	{
		server_host[i] = rxp->startp[1][i];
	}

	i = strlen(server_host) - 1;
	server_host[i] = '\0';

	//////////////////////////////////////////////////
	//                                              //
	//          サーバー接続(ソケット開始)          //
	//                                              //
	//////////////////////////////////////////////////

	printf("接続先Host -> %s\n",server_host);

	if(WSAStartup(MAKEWORD(2,0),&wsaData) != 0)
	{
		printf("ERROR '1' code -> ");
		printf("%d",WSAGetLastError());
		return;
	}

	sock =socket(AF_INET,SOCK_STREAM,0);

	if(sock == INVALID_SOCKET)
	{
		printf("ERROR '2' code -> ");
		printf("%d",WSAGetLastError());
		return;
	}

	server.sin_family = AF_INET;
	server.sin_port = htons(80);
	server.sin_addr.S_un.S_addr = inet_addr(server_host);

	host = gethostbyname(server_host);

	if(host == NULL)
	{
		if(WSAGetLastError() == WSAHOST_NOT_FOUND)
		{
			printf("ERROR '3' code -> ");
			printf("%d",WSAGetLastError());
			return;
		}

		printf("ERROR  '4' code -> ");
		printf("%d",WSAGetLastError());
		return;
	}

	addrptr = (unsigned int **)host->h_addr_list;

	server.sin_addr.S_un.S_addr = *(*addrptr);

	if(connect(sock,(struct sockaddr *)&server,sizeof(server)) == -1)
	{
		printf("ERROR '5' code -> \n");
		printf("%d",WSAGetLastError());
		return;
	}

	printf("%s\n"
	       "-------------------------------------\n",buf);

	n = send(sock,buf,(int)strlen(buf),0);

	while(n > 0)
	{
		memset(r_buf,0,sizeof(r_buf));

		n = recv(sock,r_buf,sizeof(r_buf),0);
	}

	strcpy(out_buf,r_buf);

	closesocket(sock);

	WSACleanup();
}
エラーはでなくなりました。
でも188-189行目のbufが空になってるようで、リクエストを送れないのですが、なぜ空になっているのでしょう?
ご教授ください。

閉鎖

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