I`m trying to make an email client but it doesn't work :/ Im trying to connect to google imap with SSL (without SSL i can make it) Code:
#include "StdAfx.h"
#include "openssl/ssl.h"
#include "iostream"
#include <cstdio>
#include <iostream>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <windows.h>
using namespace std;
#pragma comment(lib, "Ws2_32.lib")
#define BUFSIZE 1024
char buf[BUFSIZE];
char *msg;
WSADATA wsda;
int sock;
struct hostent *host;
struct sockaddr_in server_addr;
short int s_port = 993;
const char *s_ipaddr = "74.125.77.109";
int SSL_library_init();
SSL_METHOD *meth;
int main () {
SSL_load_error_strings();
SSL_library_init();
//RAND_seed(buf, BUFSIZE);
SSL_CTX *sslContext = SSL_CTX_new(SSLv23_client_method());
if (sslContext == NULL)
{
cout << "err\n";
}
SSL *sslConnection = SSL_new(sslContext);
if(sslConnection == NULL)
{
cout << "err\n";
}
WSAStartup(MAKEWORD(2,2), &wsda);
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(s_port);
server_addr.sin_addr.s_addr = inet_addr(s_ipaddr);
if(server_addr.sin_addr.s_addr == INADDR_NONE)
{
host = NULL;
host = gethostbyname(s_ipaddr);
if(host == NULL)
{
return false;
}
memcpy(&server_addr.sin_addr, host->h_addr_list[0], host->h_length);
}
connect(sock, (struct sockaddr *) &server_addr, sizeof(server_addr));
SSL_set_fd(sslConnection, sock);
SSL_connect(sslConnection);
cout << "Connecting:\n";
SSL_read(sslConnection, buf, sizeof(buf)-1);
cout << buf << "\n";
cout << "Logging-in:\n";
msg = "a1 login emailapp123#gmail.com PASS\n";
SSL_write(sslConnection, msg, strlen(msg));
SSL_read(sslConnection, buf, sizeof(buf)-1);
cout << buf << "\n";
cout << "INBOX\n";
msg = "a2 SELECT INBOX\n";
SSL_write(sslConnection, msg, strlen(msg));
SSL_read(sslConnection, buf, sizeof(buf)-1);
cout << buf << "\n";
system("pause");
}
And thats what i receive:
Connecting:
* OK Gimap ready for requests from 195.150.156.162 y48if37710eei.45
Logging-in:
* CAPABILITY IMAP4rev1 UNSELECT LITERAL+ IDLE NAMESPACE QUOTA ID XLIST CHILDREN
X-GM-EXT-1 UIDPLUS COMPRESS=DEFLATE
a1 OK emailapp123#gmail.com authenticated (Success)
INBOX
What should I do to make the connection right?
Thanks for every advice :-)
Chris
You need to terminate all commands sent to an imap server with both a carriage return and a line feed. Send a2 SELECT INBOX\r\n and it should work.
seems you are not terminating line command with \r\n. Please refer RFC
http://www.faqs.org/rfcs/rfc3501.html
Related
I'm new to C++ and am trying to setup a connection to a remote server but having problems getting it to work. Spec: Ubuntu 16.04, pre-installed g++ compiler and when I run the following code it returns "pre-standard C++":
if( __cplusplus == 201103L ) std::cout << "C++11\n" ;
else if( __cplusplus == 19971L ) std::cout << "C++98\n" ;
else std::cout << "pre-standard C++\n" ;
My code is as follows:
#include <iostream>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
using namespace std;
int main() {
int client;
int portNum = 80;
bool isExit = false;
int bufsize = 1024;
char buffer[bufsize];
const char ip[] = "216.58.210.36"; //google ip for test connection
const char req[] = "GET / HTTP/1.1\nHost: www.google.com"; //test
char res[bufsize];
struct sockaddr_in server_addr;
client = socket(AF_INET, SOCK_STREAM, 0);
if (client < 0) {
cout << "\nError establishing socket..." << endl;
exit(1);
}
cout << "\n=> Socket client has been created..." << endl;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(portNum);
inet_aton(ip, &server_addr.sin_addr);
if (connect(client,(struct sockaddr *)&server_addr, sizeof(server_addr)) == 0){
cout << "=> Connection to the server port number: " << portNum << endl;
}
send(client, req, bufsize, 0);
cout << "=> Awaiting confirmation from the server..." << endl;
recv(client, buffer, bufsize, 0);
cout << "=> Connection confirmed, response:" << buffer << endl;
cout << res << endl;
close(client);
return 0;
}
The client is created and the socket connects but the code hangs on the call to recv() and no response is received. I'm assuming that's because the request I'm sending is in the wrong format/data type/etc. Can anyone advise where I'm going wrong? Cheers!
You haven't sent a complete HTTP request so the server is waiting for more data.
You need to use \r\n as your line separator and your request has to end in a blank line:
const char req[] = "GET / HTTP/1.1\r\nHost: www.google.com\r\n\r\n";
Plus as others have commented you need to check for errors.
You are also sending 1024 bytes of data from a buffer which is much smaller.
I'm trying to test how to handle a client when a client sends data after a tcp server crash. I wrote a simple client and server code to provide some visual example. The client connects to the tcp server, sends data to the server, and the server reads the data.
Now I add a sleep(20) to both implementations so I have time to kill the server process (ctrl-c).
The client calls send() again and returns the length of the message. The server is not connected so probably the client will not receive a ACK packet. I assume that the client gets a RST packet but the send() has already returned. The client calls send() a 3rd time but this time, the process ends abruptly without showing any error. The last lines: cout << rsize << endl and everything below it are never called or at least that's what looks like.
When I run this, the client prints rsize values for the first two messages, but not the last one. The server prints only the first message received.
My questions are (1) why is this happening?, and (2)how can I handle correctly a server crash if the client ends abruptly?
I already read other questions related to the topic, but they don't show actual code of how to handle this.
Client code
#include <iostream>
#include <cerrno>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
using namespace std;
int main()
{
int serverPort = 65003;
char serverHost[] = "127.0.0.1";
int mySocket;
int bufferSize = 524388;
char responseBuffer[bufferSize];
struct sockaddr clientAddr;
struct sockaddr_in serverAddr;
struct in_addr ipv4addr;
serverAddr.sin_family = AF_INET;
mySocket = socket(AF_INET, SOCK_STREAM, 0);
serverAddr.sin_port = htons (serverPort);
inet_aton(serverHost, &serverAddr.sin_addr);
connect(mySocket, (struct sockaddr*) &serverAddr, sizeof(serverAddr));
int addrLen = sizeof(serverAddr);
getsockname(mySocket, &clientAddr, (socketlen_t*)&addrLen);
ssize_t rsize;
char requestMsg [] = "<This is my test Msg>";
cout << rsize << endl;
rsize = send(mySocket, requestMsg, strlen(requestMsg), 0);
if (rsize != (ssize_t)strlen(requestMsg))
{
cout << strlen(requestMsg) << endl;
cout << strerror(errno) << endl;
}
sleep(20);
char requestMsg2 [] = "<This is my 2nd test Msg>";
rsize = send(mySocket, requestMsg2, strlen(requestMsg2), 0);
cout << rsize << endl;
if (rsize != (ssize_t)strlen(requestMsg2))
{
cout << strlen(requestMsg2) << endl;
cout << strerror(errno) << endl;
}
char requestMsg3 [] = "<This is my 3rd test Msg>";
rsize = send(mySocket, requestMsg3, strlen(requestMsg3), 0);
cout << rsize << endl;
if (rsize != (ssize_t)strlen(requestMsg3))
{
cout << strlen(requestMsg3) << endl;
cout << strerror(errno) << endl;
}
return 0;
}
server code
#include <iostream>
#include <cerrno>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
using namespace std;
int main()
{
int mySocket, connSocket, serverPort;
socketlen_t clientLen;
struct sockaddr_in serverAddr, clientAddr;
int bufferSize = 256;
char buffer[bufferSize];
ssize_t rsize;
mySocket = socket(AF_INET, SOCK_STREAM, 0);
memset(&serverAddr, 0, sizeof(serverAddr));
serverPort = 65003;
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = INADDR_ANY;
serverAddr.sin_port = htons(serverPort);
bind(mySocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr));
listen(mySocket,1);
clientLen = sizeof(clientAddr);
connSocket = accept(mySocket, (struct sockaddr *) &clientAddr, &clientLen);
memset(&buffer, 0, sizeof(buffer));
rsize = read(connSocket, buffer, 255);
cout << buffer << endl;
sleep(20);
}
This error has destroyed my day. This is my second client server program. Server is iterative type. The functionality is 1.server is running all the time.
2.Client send a file name to server.
3.Server opens the file and process on its data and send information back to client.
But in the point that client receive data it produce a segmentation error. Even it can read inside the packet, but only "filename".
In fact server is opening a file and open linux dictionary file. It searches for any spelling problem etc. Finally it has line number, word and suggested word.
I have checked inside the list in server side and list has no error.
here is an abstract of my code. I appreciate if anyone can find the bug. I copy paste all code except processing on the file. Apologist in advance for long code.
Client side:
#include <pthread.h>
#include <regex.h>
#include "wrappers.h"
struct SType{
int Num;
char Word[20];
char sugg[20];
};
struct DataPktType
{
list<SType> MyList;
char filename[MAX_SIZE], message[MAX_SIZE];
int numslaves;
};
int main(int argc, char **argv){
int Sockfd;
sockaddr_in ServAddr;
char ServHost[] = "localhost";
hostent *HostPtr;
int Port = SERV_TCP_PORT;
DataPktType DataPkt;
DataPktType recDataPkt;
string filename, tempstr;
if (argc == 5){
strcpy(ServHost, argv[1]);
Port = atoi(argv[2]);
filename = string(argv[3]);
cout<<"filename= "<<filename<<endl;
DataPkt.numslaves = atoi(argv[4]);
} else{
cout << "Usage: \"client <server address> <port> <textfile> <numThreads>\".\n" << endl;
exit(1);
}
// Get the address of the host
HostPtr = Gethostbyname(ServHost);
if(HostPtr->h_addrtype != AF_INET)
{
perror("Unknown address type!");
exit(1);
}
memset((char *) &ServAddr, 0, sizeof(ServAddr));
ServAddr.sin_family = AF_INET;
ServAddr.sin_addr.s_addr = ((in_addr*)HostPtr->h_addr_list[0])->s_addr;
ServAddr.sin_port = htons(Port);
// Open a TCP socket
Sockfd = Socket(AF_INET, SOCK_STREAM, 0);
// Connect to the server
Connect(Sockfd, (sockaddr*)&ServAddr, sizeof(ServAddr));
strcpy(DataPkt.filename, argv[3]);
DataPkt.numslaves = 6;
// Write and read a message to/from the server
write(Sockfd, (char*)&DataPkt, sizeof(DataPktType));
read(Sockfd, (char*)&recDataPkt, sizeof(DataPktType));
cout<<"here"<<endl;
cout << setw(30) << left << "Filename:" << setw(20) << right << DataPkt.filename << endl;
list<SType> MyList2;
MyList2 = DataPkt.MyList;
cout<<"size= "<<MyList2.size()<<endl;
for (list<SType>::iterator it=MyList2.begin(); it!=MyList2.end(); it++)
cout << ' ' << it->Num << ' ' << it->Word << endl;
cout << "Finished\n";
close(Sockfd);
return 0;
}
Server side:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fstream.h>
#include <list>
#include <iomanip>
#include <pthread.h>
#include "wrappers.h"
#include<cstdlib>
#include<fstream>
#include<iostream>
#include<sstream>
#include <algorithm>
#define BUFSIZE 10
#define gNumThreads 6
using namespace std;
struct SType{
int Num;
char Word[20];
char sugg[20];
};
struct DataPktType
{
list<SType> MyList;
char filename[MAX_SIZE], message[MAX_SIZE];
int numslaves;
};
int main(int argc, char **argv){
int Sockfd, NewSockfd, ClntLen, Port = SERV_TCP_PORT;
sockaddr_in ClntAddr, ServAddr;
DataPktType DataPkt;
if (argc == 2){
Port = atoi(argv[1]);
}
// Open a TCP socket (an Internet stream socket)
Sockfd = Socket(AF_INET, SOCK_STREAM, 0); // socket() wrapper fn
// Setup server for development
setsockopt(Sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval);
// Bind the local address, so that the client can send to server
memset((char*)&ServAddr, 0, sizeof(ServAddr));
ServAddr.sin_family = AF_INET;
ServAddr.sin_addr.s_addr = htonl(INADDR_ANY);
ServAddr.sin_port = htons(Port);
Bind(Sockfd, (sockaddr*) &ServAddr, sizeof(ServAddr));
// Listen to the socket
Listen(Sockfd, 5);
for(;;)
{
// Wait for a connection from a client; this is an iterative server
ClntLen = sizeof(ClntAddr);
NewSockfd = Accept(Sockfd, (sockaddr*)&ClntAddr, &ClntLen);
if(NewSockfd < 0)
{
perror("Can't bind to local address!");
}
// Read a message from the client
read(NewSockfd, (char*)&DataPkt, sizeof(DataPktType));
string line;
ifstream myfile (DataPkt.filename);
if (myfile.is_open())
{
--Here is some operation I deleted to make file shorter ---
if(!found)
{
/* Add suggestion to the list */
SType S;
S.Num = lineNo;
strcpy(S.Word, result);
strcpy(S.sugg, sugg);
MyList2.push_back(S);
cout<<lineNo<<" "<<result<<" "<<sugg<<endl;
cout<<"Not found in dictionary"<<endl;
}
else
{
cout<<"found: "<<result<<" in dictionary"<<endl;
}
}
}
myfile.close();
cout<<"List before write"<<endl;
for (list<SType>::iterator it=MyList2.begin(); it!=MyList2.end(); it++)
cout << ' ' << it->Num << ' ' << it->Word << endl;
/*Send suggestion back to the client*/
DataPktType retPack;
retPack.MyList = MyList2;
//DataPkt.filename
strcpy(retPack.filename,"behzad");
write(NewSockfd, (char*)&retPack, sizeof(DataPktType));
}
else {cout << "Unable to open file"; exit(1);}
}
close(NewSockfd);
/* exit the program */
return(0);
}
output:
serverside:
1 bernard behead
Not found in dictionary
List before write
lineNo: 1 word: behzad sugg: behead
clientside:
$ ./client localhost 19431 carol.txt 6
filename= carol.txt
Finished
Segmentation Fault
You are not doing any kind of serialization over your data before send or receive.
write(Sockfd, (char*)&DataPkt, sizeof(DataPktType));
read(Sockfd, (char*)&recDataPkt, sizeof(DataPktType));
That part is completely wrong, you have a std::list into your struct, you need first to process that data before send it.
I am beginner in socket programming and I have problem with my client/server program, client can't connect to server. I have no idea why, please help. I want to fined out where is the problem.
Server:
#include <iostream>
#include <windows.h>
#include <cstdlib>
#include <stdlib.h>
#include <winsock2.h>
#include <conio.h>
#include <stdio.h>
using namespace std;
int main(int argc, char* argv[])
{
WSAData WinSockData;
WORD Version = MAKEWORD(2,1);
long SUCESSFUL;
SUCESSFUL = WSAStartup(Version,&WinSockData);
SOCKADDR_IN ADDRESS;
int AdresSize = sizeof(ADDRESS);
SOCKET sock_LISTEN;
SOCKET sock_CONNECT;
sock_CONNECT = socket(AF_INET,SOCK_STREAM,NULL);
ADDRESS.sin_addr.s_addr = inet_addr("127.0.0.1");
ADDRESS.sin_family = AF_INET;
ADDRESS.sin_port = htons(27015);
sock_LISTEN = socket(AF_INET,SOCK_STREAM,NULL);
bind(sock_LISTEN,(SOCKADDR*)&ADDRESS,sizeof(ADDRESS));
for(;;)
{
listen(sock_LISTEN,SOMAXCONN);
cout << "Waiting for connections..." << endl;
if(sock_CONNECT = accept(sock_LISTEN,(SOCKADDR*)&ADDRESS,&AdresSize))
{
cout << "Conection was found" << endl;
SUCESSFUL = send(sock_CONNECT,"Hello",5,NULL);
}
}
return 0;
}
Client:
#include <iostream>
#include <windows.h>
#include <cstdlib>
#include <stdlib.h>
#include <winsock2.h>
#include <conio.h>
#include <stdio.h>
using namespace std;
int main(int argc, char* argv[])
{
WSAData WinSockData;
WORD DLLVersion;
DLLVersion = MAKEWORD(2,1);
long SUCESSFUL;
SUCESSFUL = WSAStartup(DLLVersion,&WinSockData);
string RESPONSE;
string CONVERTER;
char MESSAGE[200];
SOCKADDR_IN ADDRESS;
SOCKET sock;
sock = socket(AF_INET,SOCK_STREAM,NULL);
ADDRESS.sin_addr.s_addr = inet_addr("127.0.0.1");
ADDRESS.sin_family = AF_INET;
ADDRESS.sin_port = htonl(27015);
cout << "Do You want to connect to this server (Y/N)" << endl;
cin >> RESPONSE;
RESPONSE[0] = tolower(RESPONSE[0]);
if(RESPONSE == "n")
{
cout << "Quiting" <<endl;
}else if (RESPONSE == "y")
{
connect(sock,(SOCKADDR*)&ADDRESS,sizeof(ADDRESS));
SUCESSFUL = recv(sock,MESSAGE,sizeof(MESSAGE),NULL);
CONVERTER = MESSAGE;
cout << CONVERTER << endl;
}else
{
cout << "Illegal response" <<endl;
}
return 0;
}
This looks odd
ADDRESS.sin_port = htons(27015);
and this looks even odder
ADDRESS.sin_port = htonl(27015);
Use htons for both.
If that doesn't work, just write
ADDRESS.sin_port = 27015;
My simple program gives no errors through the compiler and runs fine but it does not give the output it is supposed too until someone is connected. I have done a good bit of research and editing but can not figure it out.Also how do I let more than one person connect? Any help to get this to work would be appreciated. Thanks in advance!!! Code is below.
#include <iostream>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
char msg[20];
using namespace std;
int main(int argc, char *argv[])
{
cout << "Made it to main!";
int listener_d = socket(PF_INET, SOCK_STREAM, 0);
struct sockaddr_in name;
name.sin_family = PF_INET;
name.sin_port = (in_port_t)htons(30000);
name.sin_addr.s_addr = INADDR_ANY;
if(bind (listener_d, (struct sockaddr *) &name, sizeof(name)) == -1)
{
cout << "Can't bind the port!";
}
else
{
cout << "The port has been bound.";
}
listen(listener_d, 10);
cout << "Waiting for connection...";
while(1)
{
struct sockaddr_storage client_addr;
unsigned int address_size = sizeof(client_addr);
int connect_d = accept(listener_d, (struct sockaddr *)&client_addr, &address_size);
cin >> msg;
send(connect_d, msg, strlen(msg), 0);
}
return 0;
}
Maybe you should try flushing the output.
std::cout << "Waiting for connection..." << std::flush;