一个关于 recv 阻塞的问题 求高手!!!

BorrowedStory 2011-11-05 04:06:06
我用c++ 通过socket 做一个发送邮件的程序 通过esmtp实现的

程序可以 链接上smtp服务器

当程序链接上服务器的时候 服务器就会返回一个字符串 如下 (末尾有换行)
"220 irja2-171.sinamail.sina.com.cn ESMTP
"

以上的字符串可以通过调用 recv正常接受 (第一次调用recv)
但是当我发送 EHLO XXXXX@sina.com 后 再次调用 recv 的 时候就进入阻塞了 (我在 telnet 是可以正常就是的)

int SendMail::RcvServMsg(void)
{
char buf[BUFSIZE] = {0};
if(::recv(this->iSocket,buf,sizeof(buf),0) == -1)
{//接受服务器的回馈数据失败
::closesocket(this->iSocket);
this->bConn = false;
return SM_RCV_INFO_FAILD;
}
this->sRcvReturnMsg.assign(buf);
::memcpy(this->cCode,buf,3);
this->cCode[3] = 0;

return 0;
}
...全文
164 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
wjklw21 2011-12-22
  • 打赏
  • 举报
回复
问题解决了没? 其实很简单你掉了命令结束符。所以服务器没有给你发信息,你的recv就阻塞了。
你发送 “EHLO XXXXX@sina.com \r\n”试试。 你抓包看下别人邮箱发EHLO命令时后面是不是又“\r\n”
BorrowedStory 2011-11-05
  • 打赏
  • 举报
回复
我向在 telnet 中可以是因为 敲命令再敲回车执行时 就已经将换行命令添加到命令的末尾
BorrowedStory 2011-11-05
  • 打赏
  • 举报
回复
问题解决了
在每次发送的命令的末尾添加一个 \n
也就是 smtp 的命令需要在末尾添加一个换行符
xiaoguailong3 2011-11-05
  • 打赏
  • 举报
回复
你的接收在线程里做。。接收到消息再处理
xiaoguailong3 2011-11-05
  • 打赏
  • 举报
回复
你的接收在线程里做。。接收到消息再处理
BorrowedStory 2011-11-05
  • 打赏
  • 举报
回复
在telnet中发送 ehlo 的返回值

220 irja2-172.sinamail.sina.com.cn ESMTP
EHLO yangsongqbs@sina.com
250-irja2-172.sinamail.sina.com.cn
250-8BITMIME
250-SIZE 83886080
250-AUTH PLAIN LOGIN
250 AUTH=PLAIN LOGIN
BorrowedStory 2011-11-05
  • 打赏
  • 举报
回复
发送数据的 代码

// 发送指定的命令
// 成功 SM_OK
// 发送命令失败 SM_CMD_FAILD
// 发件名为空 SM_FROM_EMPTY
// 接受服务器回馈信息失败 SM_RCV_INFO_FAILD
int SendMail::SendCmdServ(int cmd)
{
int res = -1;
char buf[BUFSIZE] = {0};
assert(cmd > SMcmd::first);
assert(cmd < SMcmd::end);
if(this->sFromAddr.empty())
return SM_FROM_EMPTY;

if(cmd == SMcmd::ehlo)
{///招呼
::memset(buf,0,BUFSIZE);
strcpy(buf,"EHLO ");
::memcpy(buf+::strlen(buf),this->sFromAddr.c_str(),this->sFromAddr.length());
}else if(cmd == SMcmd::auth)
{//身份认证
::strcpy(buf,"AUTH LOGIN");
}else if(cmd == SMcmd::account)
{///发送自己的登录账户
//Base64 base;
::strcpy(buf,Base64::base64_encode(this->sFromAddr).c_str());
}else if(cmd == SMcmd::passw)
{///发送登陆密码
::strcpy(buf,Base64::base64_encode(this->sPassw).c_str());
}

if((res = send(this->iSocket , buf , strlen(buf)+1 ,0)) == -1)
{///发送命令失败
return SM_CMD_FAILD;
}

///开始获得返回的数据
if(this->RcvServMsg() < 0)
{/////接受数据失败
return SM_RCV_INFO_FAILD;
}

return SM_OK;
}
BorrowedStory 2011-11-05
  • 打赏
  • 举报
回复
但是我在 telnet 试了一下 中是可以的啊
booson_c 2011-11-05
  • 打赏
  • 举报
回复
应该是你发送数据到服器的格式可能有问题,服务器没作出回应,服务器没有返回数据,造成recv 阻塞。
BorrowedStory 2011-11-05
  • 打赏
  • 举报
回复
发送是smtp服务器做得 我管不了
bruceteen 2011-11-05
  • 打赏
  • 举报
回复
既然接受的有\n,那么发送是不是也应该有\n,不懂,猜的
BorrowedStory 2011-11-05
  • 打赏
  • 举报
回复
补充

#define BUFSIZE 1024

3,881

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧