ESMTP또는 SMTP로 메일전송중에..
글쓴이: rokmn3309 / 작성시간: 금, 2003/02/21 - 4:41오후
ESMTP로 메일전송만 하는걸 만들어 볼려고 하는데..
첨에..25포트로 접속해서.. 초기접속메세지만 받고 더이상 받지를 못하네요.
텔넷으로 직접 25포트에 접속해서 하면은 문제없이 되는데..
도저히 문제점을 찾을수가 없습니다..
허접이가.. 고수님들의 답변 부탁드립니다.
밑에건 데이터를 주고 받는 함수입니다.
원래는 주는거따로 받는거 따로였는데 하도 안되어서...
int SendGetServer(char *msg,int Fd, int size){ int nbyte=0; char buff[512]; char digit[4]; int ren; nbyte=send(Fd,msg,size,0); printf("send msg %s\n",msg); if(nbyte<0) Err("Don't Send Message To Server"); nbyte=0; nbyte=recv(Fd,buff,512,0); if(nbyte<0) Err("Don't Get Message To Server"); snprintf(digit,4,"%s",buff); switch(atoi(digit)){ case 220: ren=1; break; case 250: ren=1; break; case 251: ren=1; break; case 354: ren=2; break; default: ren=0; } printf("digit %s %d\n",buff,ren); return ren; }
다음 코드는 메인에서 ESMTP로 접속해서 데이터를 주고 받는 부분입니다.
//HELO 연결---- if(SendGetServer("EHLO lightnas.com",S_fd,17)!=1){ Err("Outbreak Of Error1"); } else{ //MAIL 요청---- len=strlen(S_md.SendMail)+12; msg=(char *) malloc(len); snprintf(msg,len,"MAIL FROM: %s",S_md.SendMail); if(SendGetServer(msg,S_fd,len) !=1){ Err("Outbreak Of Error2"); free(msg); } else{ free(msg); //RCPT 요청---- len=strlen(S_md.SendMail)+10; msg=(char *) malloc(len); snprintf(msg,len,"RCPT TO: %s",S_md.GetMail); if(SendGetServer(msg,S_fd,len)!=1){ Err("Outbreak Of Error3"); free(msg); } else{ free(msg); //DATA 요청---- if(SendGetServer("DATA",S_fd,4)!=2){ Err("Outbreak Of Error4"); } else{ //DATA를 전송한다. sprintf(test,"FROM:%s%cTo:%s%cSubject:test msg%c%c data %c.%c",S_md.SendMail,10,S_md.GetMail,10,10,10,10); SendServer(test,S_fd,strlen(test)); } //QUIT 요청---- SendServer("QUIT",S_fd,4); } } }
보통 이렇게 하면은 첨에 220 환영메세지는 받는데.. 그 다음부터나오는
250번의 MAIL부터는 대기상태에 빠져 버리는데 뭐가 문제인지.. ㅠㅠ;
Forums:
balsa.gnome.org에 libesmtp가 있습니다.
balsa가 libesmtp를 분리한지 꽤 됐으니까 안정적일 겁니다.
메일서버의 특징
보내는 텍스트의 뒤에 \r\n 을 붙이세요 그러면 됩니다.
메일서버 중에서 뒤에 저걸 붙여야 하는게 있고,
아닌것도 있거든요..
한줄의 끝은 반드시 \r\n 으로 끝나야합니다. 표준이지요.htt
한줄의 끝은 반드시 \r\n 으로 끝나야합니다. 표준이지요.
http://www.ietf.org/rfc/rfc0821.txt
page 29를 보면 <CRLF> 로 되어 있습니다....
그리고 서버의 정보를 받으실 때, line 단위로 받는 것이 좋습니다.
line 단위 receiver를 구현하셔야 나중에 또다른 문제에 봉착하는 것을
막을 수 있습니다.
흔히 실수하는 것입니다.
명심할 것은, TCP/IP에서는 보내는 회수와 받는 회수는 다를 수 있습니다.
다만, 보내는 양과, 받는 양이 같습니다.
---
http://coolengineer.com
저도 비슷한 경험이 있었던 작업이였는데.. java 포워딩 이였거?
참조 코드 붙여 봤습니다..
public void actionPerformed(ActionEvent e) {
Component c = (Component) e.getSource();
String incoming = "";
if(c == hide) {
setVisible(false);
} else if(c == clear) {
from.setText("");
to.setText("");
subject.setText("");
data.setText("");
} else if(c == send) {
if(serverName == null)
return;
try {
Socket s = new Socket(serverName, 25);
PrintStream out =
new PrintStream(s.getOutputStream());
BufferedReader in = new BufferedReader(new
InputStreamReader(s.getInputStream()));
out.println("HELO " + serverName);
out.flush();
incoming = in.readLine();
out.println("MAIL FROM:<"+from.getText()+">");
out.flush();
incoming = in.readLine();
out.println("RCPT TO:<"+to.getText()+">");
out.flush();
incoming = in.readLine();
out.println("DATA");
out.flush();
incoming = in.readLine();
out.println("Subject: "+subject.getText());
out.flush();
incoming = in.readLine();
String msg = data.getText();
out.println(msg+"\r\n.\r\n");
out.flush();
incoming = in.readLine();
out.println("QUIT");
out.flush();
setVisible(false);
to.setText("");
subject.setText("");
data.setText("");
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}
JAVA 소켓 코드 중의 일부인데 그냥 붙여봤습니다.
저 같은 경우는 소켓 연결후 다른 Layout 을 사용하여 새로운
Send Message를 포워딩 하는 경우 ... 같은 에러가 생성 되더군요 ...
표준 RFC 문서를 다 참조 하면서 느낀것이지만.. 다른 분들이 말씀하신
것 처럼... 라인 단위의 스트림으로 데이터를 받으면서
보낼때는 \r\n 으로 끝나는것으로 생성을 했습니다.
이곳에서 SMTP 서버 접속에 관한 질의를 하면서
다른것들을 봤는데..
오랠리출판사의 RFC 인터넷 이메일 프로그래밍에 관련된 책을 보고 있긴 하
면서 지금도 배우고 있지만
이런형식으로 컴파일 하고난뒤 서버 접속해서 포워딩 해보니...
아무 문제 없이 잘 되더군요 ....
좋은 하루 되세요 ....
눈 내린 들판길 가운데를 갈 때
모름지기 이지럽게 가지 말 일이다.
오늘 내가 간 자취를 따라
뒷사람의 발길이 이어지느니.....
음.. 메시지가 어떻게 되었느냐에 따라서 다를 수 있죠.
메시지 라인단위로 \r\n을 붙여주어야 되는 곳이 몇군데 이찌염.. hanafos.com 메일등
머 아닌 경우가 대부분이죠 \n만 붙여줘두 되구요..
그리고 메시지의 제일 마지막 부분은
<CR><LF>
.
<CR><LF>
로 끝나야 합니다.
이걸 지키셨는지..
댓글 달기