winsock smtp string formatting

http://stackoverflow.com/questions/14421748/winsock-string-formatting

apppend \n to tell the server that you pressed enter.... my problem is, when sending DATA command and typing in the message when sending the DATA message i need to type in multiple lines and whenever i press enter it actually sends stuff over the socket instead of it being formatted?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
//Kelvins winsock used for email

#include <iostream>
#include <winsock2.h>
#include <string>
#include <windows.h>

#define BUFFER_SIZE 2000
using namespace std;

int main(){

WSADATA wsa;
SOCKET sa;

struct sockaddr_in server;

string ip;      //ip to connect
string message; //send message
char server_reply[BUFFER_SIZE];    //server reply

int portno = 0, recv_size; // portnumber and bytes recieved

cout<< "\nInitializing winsock....\n";
cout << "Enter server: ";
cin >> ip;
cout << "Enter port number: ";
cin >> portno;

    if (WSAStartup(MAKEWORD(2,2), &wsa)!=0)         //more error checking
        cout << "Failed" << WSAGetLastError();

cout << "\ninitialized\n";


    if ((sa = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)     //make  socket with error checking
        cout << "Could not create socket " << WSAGetLastError();

cout << "\nSocket created\n";

server.sin_addr.s_addr = inet_addr ( ip.c_str() );      //initialize members of server structure
server.sin_family = AF_INET;
server.sin_port = htons(portno);


//connect with error checking
    if (connect(sa, (struct sockaddr *)&server, sizeof(server)) < 0){

        cerr << "Error: " << WSAGetLastError();

    }
cout << "connected";
cin.get(); //turns out tha tthere is an extra '\n' after i press enter for portno, and i want to get rid of it.

while (message != "./\n"){     //press key combination ./ to end server comms

        message.clear();        //clear my message each time it is send it has to get a clear buffer
                int counter = 0;

            while (counter <= BUFFER_SIZE){       //see above comment
                server_reply[counter] = '\0';
                counter++;
            }

        if ((recv_size = recv(sa, server_reply, BUFFER_SIZE, 0)) == SOCKET_ERROR){     //error checking combined with recv function

            cerr << "receive fail" << WSAGetLastError();

        }
    cout << "\nBytes recieved: " << recv_size << '\n' << server_reply << '\n';      //formatting


    cout << "Send > ";                         //send prompt
    getline(cin, message);
   message += '\r\n';                            //apppend \n to tell the server that you pressed enter.... my problem is, when sending DATA command and typing in the message
                                                // when sending the DATA message i need to type in multiple lines and whenever i press enter it actually sends stuff over the socket instead of it being formatted?
                                                //help please

          if (send(sa, message.c_str(), message.size(), 0 ) < 0){             //error checking combined with send function, used c_str for const char

            cerr << "Send fail" << WSAGetLastError();
          }


}

closesocket(sa);                    //cleanup
WSACleanup();
return 0;
}
Last edited on
There's no problem sending only parts of the data. What you need is an indicator for the end (and maybe the begin, depends on the intensity of the communication) of the message.

it is anyway likely that the server gets the message in portions.
Can you elaborate more?
Do i have to send recv function everytime i contact with the smtp server during DATA send command?
Sorry, I overlooked the smtp part. See:

http://en.wikipedia.org/wiki/Simple_Mail_Transfer_Protocol

wikipedia wrote:
The transmission of the body of the mail message is initiated with a DATA command after which it is transmitted verbatim line by line and is terminated with an end-of-data sequence. This sequence consists of a new-line (<CR><LF>), a single full stop (period), followed by another new-line. Since a message body can contain a line with just a period as part of the text, the client sends two periods every time a line starts with a period; correspondingly, the server replaces every sequence of two periods at the beginning of a line with a single one. Such escaping method is called dot-stuffing.


the end indicator is "\r\n.\r\n"

after that you may call recv(). if recv() is blocking you must not call it before the end. if not you need to call it until the answer arrives
For any serious programming I recommend you to use libcurl instead of this (unless you really want to learn how things works):
http://curl.haxx.se/
That was the pronlem.. i was calling recv during data transmission.
How would one write a client that deals with this? Any aimple telnet open source clients available?
Topic archived. No new replies allowed.