メール送信について

ActiveBasicでのプログラミングでわからないこと、困ったことなどがあったら、ここで質問してみましょう(質問を行う場合は、過去ログやWeb上であらかじめ問題を整理するようにしましょう☆)。
メッセージ
作成者
yu0627
記事: 154
登録日時: 2005年5月31日(火) 14:53

メール送信について

#1 投稿記事 by yu0627 »

ActiveBasicオフィシャルユーザーズガイドにのっているメール送信機能付きテキストエディタについて質問します。
僕の環境だと、メール送信をすると、「502 Error: command not implemented」とでます。
そして、少したつと「送信が完了しました」とでます。しかし、メールを見てみると届いていません。
ちなみにサンプルファイルでもでます。これは僕の環境だけなのでしょうか。

--------------
WinXP SP2
AB 3.x/4.0
--------------
situmon
記事: 35
登録日時: 2005年5月31日(火) 09:39
お住まい: 岐阜

#2 投稿記事 by situmon »

yu0627さんこんばんわ。

本は買っていませんが、恐らくABのサンプルと同じものですよね?
すこし調べてみたところ、プログラム自体に問題はないのですが、
送信内容を見てみると、


HELO 127.0.0.1
MAIL FROM : <aaaa@bbbb.ccc>
RCPT TO :<aaa@aaaaa.bb>
X-Mailer: Test_Mailer
Subject: aaaaaaaa

abcde
QUIT


と送信されていました。これを見る限り送信コマンドのミスです。
まず、「Subject」を送信する前に必ず「Data\r\n」を送信する必要が
あるのです。あと、本文を全て送信した後は、「.\r\n」とドットのみの
行を送信する必要があります。
これをすれば問題ないかと思います。
situmon
記事: 35
登録日時: 2005年5月31日(火) 09:39
お住まい: 岐阜

#3 投稿記事 by situmon »

さらに一箇所修正です。
「X-Mailer: Test_Mailer」 も「Data\r\n」送信後に送らなければなりませんでした。

最終的には以下の内容を送信することになります。


HELO 127.0.0.1
MAIL FROM : <aaaa@bbbb.ccc>
RCPT TO : <aaa@aaaaa.bb>
DATA
X-Mailer: Test_Mailer
Subject: aaaaaaaa

abcde
.
QUIT


となります。
ゲスト

#4 投稿記事 by ゲスト »

> さらに一箇所修正です。
> 「X-Mailer: Test_Mailer」 も「Data\r\n」送信後に送らなければなりませんでした。
>
> 最終的には以下の内容を送信することになります。
>
>
> HELO 127.0.0.1
> MAIL FROM : <aaaa@bbbb.ccc>
> RCPT TO : <aaa@aaaaa.bb>
> DATA
> X-Mailer: Test_Mailer
> Subject: aaaaaaaa
>
> abcde
> .
> QUIT
>
>
> となります。

送信部分は以下のようになっています。

コード: 全て選択


	wsprintf(buffer, Ex"HELO %s\r\n", szServerName)				'HELOコマンドを送信
	send(s, buffer, lstrlen(buffer), 0)
	FillMemory(buffer, 256, 0)
	recv(s, buffer, 256, 0)
	SetDlgItemText(hSendMail, Static_Recv, buffer)

	wsprintf(buffer, Ex"MAIL FROM : <%s>\r\n", szForm)			'MAIL FROMコマンドを送信
	send(s, buffer, lstrlen(buffer), 0)
	FillMemory(buffer, 256, 0)
	recv(s, buffer, 256, 0)
	SetDlgItemText(hSendMail, Static_Recv, buffer)

	wsprintf(buffer, Ex"RCPT TO : <%s>\r\n", szTo)				'RCPT TOコマンドを送信
	send(s, buffer, lstrlen(buffer), 0)
	FillMemory(buffer, 256, 0)
	recv(s, buffer, 256, 0)
	SetDlgItemText(hSendMail, Static_Recv, buffer)

	lstrcpy(buffer, Ex"DATA\r\n")								'DATAコマンドを送信
	send(s, buffer, lstrlen(buffer), 0)
	FillMemory(buffer, 256, 0)
	recv(s, buffer, 256, 0)
	SetDlgItemText(hSendMail, Static_Recv, buffer)

	lstrcpy(buffer, Ex"X-Mailer: Test_Mailer\r\n")				'ヘッダ部分を送信
	send(s, buffer, lstrlen(buffer), 0)

	wsprintf(buffer, Ex"Subject: %s \r\n", szSubject)			'件名を送信
	send(s, buffer, lstrlen(buffer), 0)

	lstrcpy(buffer, Ex"\r\n")
	send(s, buffer, lstrlen(buffer), 0)

	'メール本文を送信
	i=0
	i2=0
	Do
		If (TextBuffer=13 and TextBuffer[i+1]=10) or TextBuffer=0 Then
			'改行
			temporary[i2]=0
			lstrcat(temporary, Ex"\r\n")

			'送信
			send(s, temporary, lstrlen(temporary), 0)

			If TextBuffer=0 Then Exit Do

			i=i+2
			i2=0
			Continue
		End If
		temporary[i2]=TextBuffer

		i=i+1
		i2=i2+1
	Loop

	lstrcpy(buffer, Ex".\r\n")
	send(s, buffer, lstrlen(buffer), 0)
	FillMemory(buffer, 256, 0)
	recv(s, buffer, 256, 0)
	SetDlgItemText(hSendMail, Static_Recv, buffer)

	lstrcpy(buffer, Ex"QUIT\r\n")									'QUITコマンドを送信
	send(s, buffer, lstrlen(buffer), 0)
	FillMemory(buffer, 256, 0)
	recv(s, buffer, 256, 0)
	SetDlgItemText(hSendMail, Static_Recv, buffer)

内容を見る限りあなたが言っていることは全て送信しているように見えますが...。
situmon
記事: 35
登録日時: 2005年5月31日(火) 09:39
お住まい: 岐阜

#5 投稿記事 by situmon »

どうやら最新版はそのようですね。
私が確認したのは4.02のサンプルでした。
4.02.01では修正済みのようですね。
因みに確認方法はまけイヌさまのプログラム投稿掲示板に投稿した
自作ツール ネットアプリデバッグツールをSMTPサーバの代わりにしました。
最新版で確認したところ確かに問題はありませんでした。

以上ご報告まで。
最後に編集したユーザー situmon [ 2005年7月05日(火) 08:28 ], 累計 1 回
situmon
記事: 35
登録日時: 2005年5月31日(火) 09:39
お住まい: 岐阜

#6 投稿記事 by situmon »

連続レスすいません。

たった今、保存していた、4.02.01で解凍してコンパイルしないでそのままの
exeファイルで試したところ送信されませんでした。その後、
新しくダウンロードしてやってみましたが、会社では出来ましたが
出来なくなっていました。

理由は不明です。環境はどちらも
WinXP SP1です。

なにかわかり次第報告しようと思います。
situmon
記事: 35
登録日時: 2005年5月31日(火) 09:39
お住まい: 岐阜

#7 投稿記事 by situmon »

どうやら、理由はわかりませんが、パソコンの問題だった用ようです。
会社のパソコンでは確かに動作しました。
yu0627
記事: 154
登録日時: 2005年5月31日(火) 14:53

返信

#8 投稿記事 by yu0627 »

> どうやら、理由はわかりませんが、パソコンの問題だった用ようです。
> 会社のパソコンでは確かに動作しました。

最新版のABのサンプルでも同じことが起こります。
SMTPサーバーはメールの@から後ろ側を設定してあります。
situmon
記事: 35
登録日時: 2005年5月31日(火) 09:39
お住まい: 岐阜

#9 投稿記事 by situmon »

ステータスコード502は
「そのコマンドは実装されていない。コマンドそのものは知っているが、
それを実装していない(あるいは、それを使えなくしている)ときに
利用される。」
というコードです。

もしかしたら、私の自宅と同様の現象かもしれません。
またはPOP before SMTPなどでは?
ソースを見る限りレスポンスをそのまま表示するはずですが、
私の自宅では返したレスポンスと違ったステータスコードが表示されます。

私の自宅の場合、RCPT TO :<aaaaaaa@vvvvvv.ccc>に対して
レスポンスを返すと、レスポンスに関係なく、503 No Sender.が
帰ってきます。その後前回書いたように DATA と . が抜けて送信されます。
situmon
記事: 35
登録日時: 2005年5月31日(火) 09:39
お住まい: 岐阜

#10 投稿記事 by situmon »

さらに調べてみました。
送ってもいないのに勝手に帰ってくるレスポンスコードですが、
他のウェルノンポートについても調べてみましたが、やはり
ポート25のみ、挙動がおかしいようです。
というのもローカルの25番ポートに前記の自作ツールでサーバを起動し、
SMTPのプロトコルに従い、リクエストとレスポンスを送受信すると、
送っていないはずのレスポンスが返ってきたり、QUITにレスポンスすると
コネクションが切れたりします。
netstat -a で25番に自作ツール以外何も動いていないのは確認しました。
Windowsの仕様かと思ったんですが、今までこんなことありませんでした。
常駐ソフトの可能性もありますが、FW(ZoneAlarm)は終了させてあります。

この辺の仕様に詳しい方解説お願いします。
OSはWinXP HEです。98SEでも試しましたが問題はおきませんでした。
yu0627
記事: 154
登録日時: 2005年5月31日(火) 14:53

返信

#11 投稿記事 by yu0627 »

> さらに調べてみました。
> 送ってもいないのに勝手に帰ってくるレスポンスコードですが、
> 他のウェルノンポートについても調べてみましたが、やはり
> ポート25のみ、挙動がおかしいようです。
> というのもローカルの25番ポートに前記の自作ツールでサーバを起動し、
> SMTPのプロトコルに従い、リクエストとレスポンスを送受信すると、
> 送っていないはずのレスポンスが返ってきたり、QUITにレスポンスすると
> コネクションが切れたりします。
> netstat -a で25番に自作ツール以外何も動いていないのは確認しました。
> Windowsの仕様かと思ったんですが、今までこんなことありませんでした。
> 常駐ソフトの可能性もありますが、FW(ZoneAlarm)は終了させてあります。
>
> この辺の仕様に詳しい方解説お願いします。
> OSはWinXP HEです。98SEでも試しましたが問題はおきませんでした。

返信が遅れてすみません。ちょっとプログラムの改造にてこずっていたので。
...っと思ったら作ってもなぜかソフトが落ちます。
以下がソースです。

コード: 全て選択


	FillMemory(buffer, 256, 0)
	recv(s, buffer, 256, 0)
	SetDlgItemText(hSendMail, Static_Recv, buffer)
	lstrcpy(StrPtr(Recvtemp), buffer)

	wsprintf(buffer, Ex"HELO %s\r\n", szServerName)				'HELOコマンドを送信
	send(s, buffer, lstrlen(buffer), 0)
	FillMemory(buffer, 256, 0)
	recv(s, buffer, 256, 0)
	SetDlgItemText(hSendMail, Static_Recv, buffer)
	lstrcat(StrPtr(Recvtemp), buffer)

	wsprintf(buffer, Ex"MAIL FROM : <%s>\r\n", szForm)			'MAIL FROMコマンドを送信
	send(s, buffer, lstrlen(buffer), 0)
	FillMemory(buffer, 256, 0)
	recv(s, buffer, 256, 0)
	lstrcat(StrPtr(Recvtemp), buffer)
	SetDlgItemText(hSendMail, Static_Recv, buffer)
	debug

	wsprintf(buffer, Ex"RCPT TO : <%s>\r\n", szTo)				'RCPT TOコマンドを送信
	send(s, buffer, lstrlen(buffer), 0)
	FillMemory(buffer, 256, 0)
	recv(s, buffer, 256, 0)
	lstrcat(StrPtr(Recvtemp), buffer)
	SetDlgItemText(hSendMail, Static_Recv, buffer)

	lstrcpy(buffer, Ex"DATA\r\n")								'DATAコマンドを送信
	send(s, buffer, lstrlen(buffer), 0)
	FillMemory(buffer, 256, 0)
	recv(s, buffer, 256, 0)
	lstrcat(StrPtr(Recvtemp), buffer)
	SetDlgItemText(hSendMail, Static_Recv, buffer)

	lstrcpy(buffer, Ex"X-Mailer: Test_Mailer\r\n")				'ヘッダ部分を送信
	send(s, buffer, lstrlen(buffer), 0)

	wsprintf(buffer, Ex"Subject: %s \r\n", szSubject)			'件名を送信
	send(s, buffer, lstrlen(buffer), 0)

	lstrcpy(buffer, Ex"\r\n")
	send(s, buffer, lstrlen(buffer), 0)

	'メール本文を送信
	i=0
	i2=0
	Do
		If (TextBuffer=13 and TextBuffer[i+1]=10) or TextBuffer=0 Then
			'改行
			temporary[i2]=0
			lstrcat(temporary, Ex"\r\n")

			'送信
			send(s, temporary, lstrlen(temporary), 0)

			If TextBuffer=0 Then Exit Do

			i=i+2
			i2=0
			Continue
		End If
		temporary[i2]=TextBuffer

		i=i+1
		i2=i2+1
	Loop

	lstrcpy(buffer, Ex".\r\n")
	send(s, buffer, lstrlen(buffer), 0)
	FillMemory(buffer, 256, 0)
	recv(s, buffer, 256, 0)
	lstrcat(StrPtr(Recvtemp), buffer)
	SetDlgItemText(hSendMail, Static_Recv, buffer)

	lstrcpy(buffer, Ex"QUIT\r\n")									'QUITコマンドを送信
	send(s, buffer, lstrlen(buffer), 0)
	FillMemory(buffer, 256, 0)
	recv(s, buffer, 256, 0)
	lstrcat(StrPtr(Recvtemp), buffer)
	SetDlgItemText(hSendMail, Static_Recv, buffer)

	'ソケットへの接続を閉じる
	shutdown(s, SD_BOTH)
	closesocket(s)

	'WinSockが使用したメモリを開放
	WSACleanup()

	SetDlgItemText(hSendMail, Static_Recv, "送信が完了しました")
	SetDlgItemText(hSendMail, RecvLog, Recvtemp)

なぜか途中で落ちます。デバッグするとデバッガも落ちます。そしてProjectEditorも落ちます。
なんか出来ていた時のをみると「HEAP...」とか書いてあります。なぜかString型変数の開放に失敗するようです。
Sinryow
記事: 141
登録日時: 2005年5月31日(火) 09:34
お住まい: 北海道
連絡する:

#12 投稿記事 by Sinryow »

Recvtempにメモリが確保されていない状態でlstrcatをかけたために失敗しているのでしょう。
この場合は,単に

Recvtemp=Recvtemp+buffer

などとすればよいです。(BytePtr→Stringの変換はAB側でしてくれる)
' ============================================================
' Sinryow Game Home Page - http://www.sinryow.net/
' Sinryow ActiveBasic Center - http://ab.sinryow.net/
' ============================================================
yu0627
記事: 154
登録日時: 2005年5月31日(火) 14:53

ありがとうございます

#13 投稿記事 by yu0627 »

> Recvtempにメモリが確保されていない状態でlstrcatをかけたために失敗しているのでしょう。
> この場合は,単に
>
> Recvtemp=Recvtemp+buffer
>
> などとすればよいです。(BytePtr→Stringの変換はAB側でしてくれる)

教えてくださりありがとうございます。早速改良してログを出してみました。
いかがそのコードです。

コード: 全て選択


220 ********.***.ne.jp ESMTP Postfix

250 smtp.*****.***.ne.jp

501 Syntax: MAIL FROM: <address>

503 Error: need MAIL command

503 Error: need RCPT command

502 Error: command not implemented

502 Error: command not implemented
500 Error: bad syntax
502 Error: command not implemented
500 Error: bad syntax
502 Error: command not implemented
502 Error: command not implemented
502 Error: command not implemented
502 Error: command not implemeTK
プライバシーのため、ホスト名などは伏せてあります。
「MAIL」「RCPT」コマンドが送信されていないようです。
なお、POP before SMTPではないです。なぜならOEのアカウントの設定の送信メールサーバーの設定に「このサーバーは認証が必要」を設定する必要がないからです。POP before SMTPをしているサーバーの設定には設定してありますので。
Abs

#14 投稿記事 by Abs »

私の環境では、以下の修正で送信できました。
おまけとして、追加コードも載せておきます。
Ab4.02.01用サンプル + winxp(sp2)

変更箇所:
1.
wsprintf(buffer, Ex"MAIL FROM : <%s>\r\n", szForm) 'MAIL FROMコマンドを送信
        ↓
wsprintf(buffer, Ex"MAIL FROM:<%s>\r\n", szFrom) 'MAIL FROMコマンドを送信

2.
wsprintf(buffer, Ex"RCPT TO : <%s>\r\n", szTo) 'RCPT TOコマンドを送信
        ↓
wsprintf(buffer, Ex"RCPT TO:<%s>\r\n", szTo) 'RCPT TOコマンドを送信

追加コード:
SetDlgItemText(hSendMail,Static_Recv,buffer)
  ●ここへ、※1のコードを追加してください。
lstrcpy(buffer, Ex"X-Mailer: Test_Mailer\r\n") 'ヘッダ部分を送信

※1
'FROMを送信
wsprintf(buffer, Ex"From: %s <%s>\r\n", "yu0627", szFrom)
send(s, buffer, lstrlen(buffer), 0)

'TOを送信
wsprintf(buffer, Ex"To: %s <%s>\r\n", "yu0627 Jr.", szTo)
send(s, buffer, lstrlen(buffer), 0)

あくまでもサンプルコードですので、実際には、まだ処理が必要です。
(文字化けをおこす事がある。)

件名:
 S-JIS -> JIS -> Base64 -> ISO-2022-JPヘッダ付加して送信。
 例:"test"をSubjectとして送信する場合。
   "Subject: =?ISO-2022-JP?B?dGVzdA==?=\r\n"

本文:
 SJis -> Jis に変換して送信。

添付ファイル:
 BASE64 に変換して送信。

その他:
 サーバが返すコードの処理(エラーとか)
 エンコード形式などの送信。
 "Content-Transfer-Encoding: 7bit\r\n"
 "Content-Type: text/plain; charset=ISO-2022-JP\r\n" など…。

参考:
http://www.kumei.ne.jp/c_lang/
私も参考にしました。但し、ここだけでは解決しません。

テスト用ツール:
このツールで他のメーラーの送信内容も参考に出来る。
http://www.vector.co.jp/soft/winnt/net/se260068.html

# 私もメール送受信クラスを作成するときに、何度も送受信したりで結構苦労しました。
でも、企画倒れで全然使ってませんが。(笑)
yu0627
記事: 154
登録日時: 2005年5月31日(火) 14:53

返信@yu0627

#15 投稿記事 by yu0627 »

ありがとうございます。おかげで送信ができるようになりました。
ただ、タブがうまく送信されません。どうすればいいでしょうか。

コード: 全て選択


	wsprintf(buffer, Ex"HELO %s\r\n", szServerName)				'HELOコマンドを送信
	send(s, buffer, lstrlen(buffer), 0)
	FillMemory(buffer, 256, 0)
	recv(s, buffer, 256, 0)
	SetDlgItemText(hSendMail, Static_Recv, buffer)
	Recvtemp=Recvtemp + Ex"\r\n" + buffer

	wsprintf(buffer, Ex"MAIL FROM:<%s>\r\n", szForm)			'MAIL FROMコマンドを送信
	send(s, buffer, lstrlen(buffer), 0)
	FillMemory(buffer, 256, 0)
	recv(s, buffer, 256, 0)
	Recvtemp=Recvtemp + Ex"\r\n" + buffer
	SetDlgItemText(hSendMail, Static_Recv, buffer)

	wsprintf(buffer, Ex"RCPT TO:<%s>\r\n", szTo)				'RCPT TOコマンドを送信
	send(s, buffer, lstrlen(buffer), 0)
	FillMemory(buffer, 256, 0)
	recv(s, buffer, 256, 0)
	Recvtemp=Recvtemp + Ex"\r\n" + buffer
	SetDlgItemText(hSendMail, Static_Recv, buffer)

	lstrcpy(buffer, Ex"DATA\r\n")								'DATAコマンドを送信
	send(s, buffer, lstrlen(buffer), 0)
	FillMemory(buffer, 256, 0)
	recv(s, buffer, 256, 0)
	SetDlgItemText(hSendMail, Static_Recv, buffer)
	Recvtemp=Recvtemp + Ex"\r\n" + buffer

	wsprintf(buffer, Ex"From: %s <%s>\r\n", szFormName, szForm)	'FROMを送信
	send(s, buffer, lstrlen(buffer), 0)

	wsprintf(buffer, Ex"To: %s <%s>\r\n", szToName, szTo)		'TOを送信
	send(s, buffer, lstrlen(buffer), 0)

	lstrcpy(buffer, Ex"X-Mailer: Test_Mailer\r\n")				'ヘッダ部分を送信
	send(s, buffer, lstrlen(buffer), 0)

	wsprintf(buffer, Ex"Subject: %s \r\n", szSubject)            '件名を送信
    send(s, buffer, lstrlen(buffer), 0)

	lstrcpy(buffer, Ex"\r\n")
	send(s, buffer, lstrlen(buffer), 0)

	'メール本文を送信
	i=0
	i2=0
	Do
		If (TextBuffer=13 and TextBuffer[i+1]=10) or TextBuffer=0 Then
			'改行
			temporary[i2]=0
			lstrcat(temporary, Ex"\r\n")

			'送信
			send(s, temporary, lstrlen(temporary), 0)

			If TextBuffer=0 Then Exit Do

			i=i+2
			i2=0
			Continue
		End If
		temporary[i2]=TextBuffer

		i=i+1
		i2=i2+1
	Loop

	lstrcpy(buffer, Ex".\r\n")
	send(s, buffer, lstrlen(buffer), 0)
	FillMemory(buffer, 256, 0)
	recv(s, buffer, 256, 0)
	Recvtemp=Recvtemp + Ex"\r\n" + buffer
	SetDlgItemText(hSendMail, Static_Recv, buffer)

	lstrcpy(buffer, Ex"QUIT\r\n")									'QUITコマンドを送信
	send(s, buffer, lstrlen(buffer), 0)
	FillMemory(buffer, 256, 0)
	recv(s, buffer, 256, 0)
	Recvtemp=Recvtemp + Ex"\r\n" + buffer
	SetDlgItemText(hSendMail, Static_Recv, buffer)

	'ソケットへの接続を閉じる
	shutdown(s, SD_BOTH)
	closesocket(s)

	'WinSockが使用したメモリを開放
	WSACleanup()
返信する