Доброго времени суток! Нужно было написать почтовый клиент на сокетах, использующего протокол POP3 для чтения сообщений. Немного погуглив, наклакал программу
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <memory.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#define BUF_SIZE 4096
#define CLIENT_PORT 1234
#define SERVER_PORT 110
int transaction (int s, char* mes) //Функция отправки запросов POP3-серверу
{
int recv_len;
char buf[BUF_SIZE];
strcpy (buf, mes);
send (s, buf, strlen(buf), 0); //Отправить запрос
recv_len = recv (s, buf, BUF_SIZE, 0); //Получить ответ
buf[recv_len] = '\0';
fprintf (stderr, "< %s", buf);
if (!strncmp (buf, "+OK", 3))
return 0;
else
return 1;
}
int establ_connect (int* s, char* h, char* u, char* p) //функция установления соединения
{
int rez;
char buf[BUF_SIZE];
struct hostent *hp;
struct sockaddr_in clnt_sin;
struct sockaddr_in srv_sin;
//создание сокета
*s = socket (AF_INET, SOCK_STREAM, 0);
memset ((char *)&clnt_sin, '\0', sizeof(clnt_sin));
clnt_sin.sin_family = AF_INET;
clnt_sin.sin_addr.s_addr = INADDR_ANY;
clnt_sin.sin_port = CLIENT_PORT;
bind (*s, (struct sockaddr *)&clnt_sin, sizeof(clnt_sin));
memset ((char *)&srv_sin, '\0', sizeof(srv_sin));
srv_sin.sin_family = AF_INET;
hp = gethostbyname (h); //адрес узла по имени
memcpy ((char *)&srv_sin.sin_addr, hp->h_addr, hp->h_length); //копирование адреса удаленного узла в структуру srv_sin
srv_sin.sin_port = htons(SERVER_PORT); //заполнения адреса порта сервера с сетевым порядком расположения байтов
fprintf (stderr, "Connecting to \'%s\'\n", h);
rez = connect (*s, (struct sockaddr *)&srv_sin, sizeof(srv_sin));
//fprintf (stderr, "%d: %s\n", rez, strerror(errno));
rez = recv (*s, buf, BUF_SIZE, 0);
buf[rez] = '\0';
//fprintf (stderr, "< %s", buf);
sprintf (buf, "USER %s\n", u);
transaction (*s, buf); //отправка команды USER логин
sprintf (buf, "PASS %s\n", p);
transaction (*s, buf); //отправка команды PASS пароль
}
int main (int argc, char** argv)
{
char host[BUF_SIZE];
char user[BUF_SIZE];
char pass[BUF_SIZE];
fprintf (stderr, "host: ");
fscanf (stdin, "%s", &host); //получение имени хоста
fprintf (stderr, "user: ");
fscanf (stdin, "%s", &user); //получение логина
fprintf (stderr, "pass: ");
fscanf (stdin, "%s", &pass); //получение пароля
fprintf (stderr, "\nUsing\n\thost: %s\n\tuser: %s\n\tpass: %s\n\n", host, user, pass);
int sock;
establ_connect (&sock, host, user, pass); //установление соединения с сервером
char buf[BUF_SIZE];
int len;
//Вывод команд
fprintf (stderr,"Type any of the following commands:\nSTAT - display number of mails and total size\nLIST - list all mails' sizes\nLIST n - list n mail's size\nRETR n - retrieve n's mail\nDELE n - delete n's mail\nNOOP - do nothing\nQUIT - shut down the connection and exit\n");
while (1) //ввод команд
{
fprintf (stderr, "> ");
gets(buf); //Чтение введенной команды в buf
len = strlen(buf);
buf[len] = '\n';
buf[len+1] = '\0';
if (strlen(buf) > 1) //если введена команда
{
transaction (sock, buf); //послать запрос серверу и получить ответ на введенную команду
if (!strcmp(buf, "QUIT\n")) //если выход
{
shutdown(sock, 0); //закрытие связи
close (sock); //закрытие сокета
exit(0);
}
}
}
}
Все вроде работает Даже результат такой:
./a.out
host: rk6lab.bmstu.ru
user: rk6stud
pass: rk6stud
Using
host: rk6lab.bmstu.ru
user: rk6stud
pass: rk6stud
Connecting to 'rk6lab.bmstu.ru'
< +OK Password required for rk6stud.
< +OK rk6stud has 3 visible messages (0 hidden) in 16921 octets.
Type any of the following commands:
STAT - display number of mails and total size
LIST - list all mails' sizes
LIST n - list n mail's size
RETR n - retrieve n's mail
DELE n - delete n's mail
NOOP - do nothing
QUIT - shut down the connection and exit
> RETR 2
< +OK 4194 octets
Return-Path: <mr.pink999@mail.ru>
Received: from mailhub.bmstu.ru (mailhub.bmstu.ru [195.19.32.15])
by bigor.bmstu.ru (8.13.8+Sun/8.13.8) with ESMTP id v4M9v2q8005908
for <rk6stud@rk6.bmstu.ru>; Mon, 22 May 2017 13:57:02 +0400 (MSD)
Received: from localhost (localhost [127.0.0.1])
by mailhub.bmstu.ru (Postfix) with ESMTP id 547F38DB1B
for <rk6stud@rk6.bmstu.ru>; Mon, 22 May 2017 12:59:31 +0300 (MSK)
X-Virus-Scanned: amavisd-new at mailhub.bmstu.ru
X-Spam-Flag: NO
X-Spam-Score: -2.049
X-Spam-Level:
X-Spam-Status: No, score=-2.049 tagged_above=-9999 required=10
tests=[AWL=0.350, BAYES_00=-1.9, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1,
FREEMAIL_ENVFROM_END_DIGIT=0.25, FREEMAIL_FROM=0.001,
FREEMAIL_REPLYTO_END_DIGIT=0.25, FROM_IS_REPLY_TO=-0.1,
HTML_MESSAGE=0.001, MSGID_FROM_MTA_HEADER=0.001,
RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001]
autolearn=no autolearn_force=no
Authentication-Results: mailhub.bmstu.ru (amavisd-new);
dkim=pass (1024-bit key) header.d=mail.ru
Received: from mailhub.bmstu.ru ([127.0.0.1])
by localhost (mailhub.bmstu.ru [127.0.0.1]) (amavisd-new, port 10024)
with ESMTP id QAe95A39jlAu for <rk6stud@rk6.bmstu.ru>;
Mon, 22 May 2017 12:59:29 +0300 (MSK)
Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=185.5.136.86; helo=f415.i.mail.ru; envelope-from=mr.pink999@mail.ru; receiver=rk6stud@rk6.bmstu.ru
Received: from f415.i.mail.ru (f415.i.mail.ru [185.5.136.86])
by mailhub.bmstu.ru (Postfix) with ESMTPS id E2CB68DAEC
for <rk6stud@rk6.bmstu.ru>; Mon, 22 May 2017 12:59:29 +0300 (MSK)
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mail.ru; s=mail2;
h=ReSent-From:ReSent-To:Content-Type:Message-ID:Reply-To:Date:MIME-Version:Subject:To:From; bh=sr2PsCbNU8rZ+yDJoHCNzzJviwyaPb4J3ssC3RSGe30=;
b=Jt9MT0GJx1twXr7i0YwO0Oo/K6Uel6PRAEJPVkN98LUoVduH6KEYmaUzLeRWfa2m+G02bBs0OxslxHM5/r+MNLX01NK7UURzrQIFP10fpkimKytRoG5F2YabI2EnPprdeu2KI91p99Wbt09UkJ2LbOpBC4x2Ktzg6Lbybkh4JoA=;
Received: by f415.i.mail.ru with local (envelope-from <mr.pink999@mail.ru>)
id 1dCk7T-0008UQ-Kh
for rk6stud@rk6.bmstu.ru; Mon, 22 May 2017 12:59:19 +0300
Delivered-To: mr.pink999@mail.ru
X-Received: from [176.59.50.204] (ident=mail)
by f171.i.mail.ru with local (envelope-from <mr.pink999@mail.ru>)
id 1dCk4C-0002Dn-N5
for mr.pink999@mail.ru; Mon, 22 May 2017 12:55:56 +0300
X-Received: by e.mail.ru with HTTP;
Mon, 22 May 2017 12:55:56 +0300
From: =?UTF-8?B?0J/QsNCy0LXQuyDQodC+0LvQvtCy0YzQtdCy?= <mr.pink999@mail.ru>
To: =?UTF-8?B?cms2c3R1ZA==?= <rk6stud@rk6.bmstu.ru>
Subject: =?UTF-8?B?SGkgaXRzIG1l?=
MIME-Version: 1.0
X-Mailer: Mail.Ru Mailer 1.0
Date: Mon, 22 May 2017 12:55:56 +0300
Reply-To: =?UTF-8?B?0J/QsNCy0LXQuyDQodC+0LvQvtCy0YzQtdCy?= <mr.pink999@mail.ru>
X-Priority: 3 (Normal)
Message-ID: <1495446956.208564503@f171.i.mail.ru>
Content-Type: multipart/alternative;
boundary="--ALT--2f95a6a21495446956"
Received: by e.mail.ru with HTTP;
Mon, 22 May 2017 12:59:19 +0300
ReSent-To: =?UTF-8?B?cms2c3R1ZA==?= <rk6stud@rk6.bmstu.ru>
ReSent-From: =?UTF-8?B?0J/QsNCy0LXQuyDQodC+0LvQvtCy0YzQtdCy?= <mr.pink999@mail.ru>
Authentication-Results: f415.i.mail.ru; auth=pass smtp.auth=mr.pink999@mail.ru smtp.mailfrom=mr.pink999@mail.ru
X-7FA49CB5: 0D63561A33F958A5D5C897E977929DCA44EFE066B087F2258E5DB6005DE8E918725E5C173C3A84C33DA51A825E5C8E7BB66AB3901264E1431D6A3D1828C120DEC4224003CC836476C0CAF46E325F83A50BF2EBBBDD9D6B0F05F538519369F3743B503F486389A921A5CC5B56E945C8DA
X-Mras: OK
X-Spam: undefined
Resent-Message-Id: <20170522095931.547F38DB1B@mailhub.bmstu.ru>
Resent-Date: Mon, 22 May 2017 12:59:31 +0300 (MSK)
X-UIDL: 0jL"!iTD"!m-n"!ZCi!!
Status: RO
----ALT--2f95a6a21495446956
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: base64
CgpIb3cgYXJlIHlvdSB0b2RheT8gV2VhdGhlciBpcyBuaWNlIQotLQpQYXVs
----ALT--2f95a6a21495446956
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: base64
CjxIVE1MPjxCT0RZPjxwIHN0eWxlPSdtYXJnaW4tdG9wOiAwcHg7JyBkaXI9Imx0ciI+PGJyPgpI
b3cgYXJlIHlvdSB0b2RheT8gV2VhdGhlciBpcyBuaWNlITxicj4KLS08YnI+ClBhdWw8L3A+Cjwv
Qk9EWT48L0hUTUw+Cg==
----ALT--2f95a6a21495446956--
.
Собсна в чем проблема. Пишу отчет преподавателю и он ждет от меня объяснений. А я не могу понять, что он требует. Сначала спросил как определяется конец письма. Загуглил. Нашел что .CRLF. Вот что в ответе получил от него:
Один единственный recv? А если ответ (тело письма) длинный?
"окончание текста письма определяется строкой .CRLF"
Откуда эта информация?
Получается, что в общем случае одного recv'a не хватает и он не сможет все письмо принять и нужно recv'ом принимать, пока не конец письма? Или что он требует? С одним recv'oм все прекрасно работает, как видите. Очень нужна ваша помощь!
Проблема в том, что протокол интерактивный, после окончания передачи сервер перейдет в ожидание новых команд, а вы все еще будете ждать окончания письма. И сервер ждет, и вы ждете, потом все отваливается по таймауту. Вот если бы сервер сразу закрывал соединение - это отличный код. Это для блокирующего режима. В асинхронном режиме еще хуже: будет получено только то, что успело приехать.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Подскажите, почему для вложенного тега li не работает свойство line-height?
При нажатии на ссылку в мобильном Хроме, она выделяется фоновым (светлосиним) цветом:hover, :focus и :active при отладке такого эффекта не создают