我一直在尝试为 yahoo 编写一个 POP3
客户端,但每当我发送有效命令时,我都无法从 socket
读取。我知道创建通过网络处理纯文本
的应用程序并不安全,但我现在只是想了解有关 POP3
的更多信息。
我正在使用 QT
创建图形界面,但我认为这目前无关紧要。
首先,我通过在终端中运行简单的命令来确保雅虎支持纯文本
通信:
telnet pop.mail.yahoo.com 110
+OK hello from popgate-0.8.0.504347 pop011.mail.ir2.yahoo.com
user validuser
+OK password required.
pass validpassword
+OK maildrop ready, 100 messages (134513 octets) (13531)
这就是我处理打开连接的方式:
int openConnection(char ip[], int port)
{
//descriptor of socket
int sd;
struct sockaddr_in server;
//fill in server structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr (ip);
server.sin_port = htons (port);
//create communication socket
if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
{
//if cannot create, return error
return -2;
}
if (connect (sd, (struct sockaddr *) &server,sizeof (struct sockaddr)) == -1)
{
return -1;
}
return sd;
//values to be returned
//-2 - could not create socket
//-1 - could not connect to server
//socket descriptor in case of success
}
当我调用时,创建套接字和连接没有问题
int sd = openConnection ("188.125.68.106", 110)
(188.125.68.106 = pop.mail.yahoo.com 的 IP)
我什至可以在不使用 select 或 epoll 的情况下阅读欢迎消息。
char message[80];
read (sd, message, 80);
消息:
+OK hello from popgate-0.8.0.504347 pop011.mail.ir2.yahoo.com
我还可以发送各种无效命令,并读取返回的错误
int sd = openConnection ("188.125.68.106", 110)
write (sd,"this command is invalid",80);
char messageFromS [80];
bzero (messageFromS, 80);
read (sd,messageFromS,80);
我从字里行间得到了一些东西
-ERR invalid command
但是每当我发送有效命令时,我的客户端在调用 read 后就会卡住,我必须强制退出
write (sd,"user validuser",80);
char messageFromS [80];
bzero (messageFromS, 80);
read (sd,messageFromS,80);
后来,我决定使用select()
,因为我知道这是一个很好的做法,也许它可以给出好的结果
//function returns true (1) if we can read from the socket
bool isClosed(int sock)
{
fd_set rfd;
FD_ZERO(&rfd);
FD_SET(sock, &rfd);
timeval tv;
//timeout value is set to 5 seconds
tv.tv_sec = 5;
select(sock+1, &rfd, 0, 0, &tv);
if (!FD_ISSET(sock, &rfd))
return false;
int n = 0;
ioctl(sock, FIONREAD, &n);
return n == 0;
}
但似乎每当我打电话
isClosed(sd)
它总是返回 True。
这就是我想不出任何其他选择的地方。 Telnet 有哪些功能是我的微型客户端所没有的?
编辑:谢谢您的回答。 我逐字节读取所有收到的消息,直到找到终止字符(显然它不是 NULL),并且在仔细阅读 pop3 ( https://www.rfc-editor.org/rfc/rfc1081 ) 的 RFC 后,我意识到我不是“t 正确结束我的命令。我应该在发送的所有命令的末尾附加“\r”和“\n”。 我还检查了 select () 命令,该命令返回 -1 并设置 tv.tv_usec = 0 这几乎解决了这个问题。
最佳答案
谢谢您的回答。 我逐字节读取所有收到的消息,直到找到终止字符(显然它不是 NULL),并且在仔细阅读 pop3 ( https://www.rfc-editor.org/rfc/rfc1081 ) 的 RFC 后,我意识到我不是“t 正确结束我的命令。我应该在发送的所有命令的末尾附加“\r”和“\n”。 我还检查了 select () 命令,该命令返回 -1 并设置 tv.tv_usec = 0 这几乎解决了这个问题。
– Shoshinsha Purogurama
关于c - 在 Linux 中使用 C 的明文 POP3 客户端 - 向服务器发送命令后读取错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20452072/