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);
}
Related
I am currently trying to create a C++ TCP IP Client that can send a specific string to a server, which makes the server send back a string with some numbers I need to use.
Specifically I need to send the string "getpos", and only that.
This works perfectly on the first loop, but on the second loop and onward. Whenever I try to send "getpos" again, it will overlap "getpos" with the numbers I previously recieved from the server and send that like:
"getpos20,123,24"
It's like the buffer or something hasn't cleared.
My program works perfectly when connecting to a Python server, but not a C++ server.
I have looked through others with similar issues, and tried various fixes. Nothing has worked so far.
Here is my current client code (on Linux):
#include <iostream>
#include <sys/types.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <string.h>
#include <string>
int main()
{
// Create a socket
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1)
{
return 1;
}
// Create a hint structure for the server we're connecting with
int port = PORTHERE;
std::string ipAddress = "IPNUMBERHERE";
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(port);
inet_pton(AF_INET, ipAddress.c_str(), &hint.sin_addr);
std::cout << "listening" << std::endl;
// Connect to the server on the socket
int connectRes = connect(sock, (sockaddr*)&hint, sizeof(hint));
if (connectRes == -1)
{
return 1;
}
std::cout << "connected" << std::endl;
// While loop:
char buf[4096];
int buflen = 1024;
while(true){
// Send to server
std::string getmypos = "getpos";
int sendRes = send(sock, getmypos.c_str(), getmypos.size(), 0);
if (sendRes == -1){
std::cout << "Could not send to server! Whoops!" << std::endl;
continue;
}
// Wait for response
memset(buf, 0, 4096);
int bytesReceived = recv(sock, buf, buflen, 0);
if (bytesReceived == -1)
{
std::cout << "There was an error getting response from server" << std::endl;
}
else
{
// Display response
std::cout << "SERVER> " << std::string(buf, bytesReceived) << std::endl;
sleep(1);
}
}
// Close the socket
close(sock);
return 0;
}
Hi I am new in Socket Programming and try to create a client server applciation using in which my server is Camera and client in my C++ application.
When I see the packet transfer between computer and camera it showing that camera is sending more than 150000 packets after that it stops. But when I am receving that I am able to receive 400 - 450 packets at a time after that the recvfrom function goes to waiting state. and If I again run that exe file without stopping the previous one it again receive 400-450 packets.
Code for Receving Packets
SOCKET out1 = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
if (out1 == INVALID_SOCKET)
{
cout << out1 << endl;
}
server.sin_family = AF_INET;
server.sin_port = htons(3956);
inet_pton(AF_INET, "192.168.1.140", &server.sin_addr);
int serverLength = sizeof(server);
connect(out1, (sockaddr*)&server, serverLength);
while (1)
{
memset(buf, 0, sizeof(buf));
int bytesIn = recvfrom(out1, buf, 1444, 0, (sockaddr*)&server, &serverLength);
if (bytesIn > 0)
{
cout << "Image Received :" << bytesIn <<packet_counter << endl;
packet_counter++;
}
else
{
cout << "Not Received : " << endl;
}
}
I am running the .exe with the administrator rights.
So can anyone please tell me why the recvfrom function is going in waiting state.
Thanks in Advance.
EDIT:-
Sorry that I am providing the whole code.
#include <stdio.h>
#include <Windows.h>
#include <thread>
#include <WinSock2.h>
// Library
#pragma comment(lib, "ws2_32.lib")
using namespace std;
//***** Function Decleration *****//
void _packetConfig(SOCKET);
void _sendPacket(SOCKET, const char*, int, int);
// Global Variable
sockaddr_in server;
//***** Main Function *****//
void main(char argc, char* argv[])
{
WSADATA data;
WORD version = MAKEWORD(2, 2);
if(WSAStartup(version, &data) == SOCKET_ERROR)
{
cout << "Can't Start Socket" << WSAGetLastError<<endl;
return;
}
char buf[2000];
SOCKET out1 = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
if (out1 == INVALID_SOCKET)
{
cout << out1 << endl;
}
server.sin_family = AF_INET;
server.sin_port = htons(3956);
inet_pton(AF_INET, "192.168.1.140", &server.sin_addr);
int serverLength = sizeof(server);
connect(out1, (sockaddr*)&server, serverLength);
int packet_counter = 0;
SOCKET out = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
_packetConfig(out);
cout << "Inside Main" << endl;
while (1)
{
//connect(out1, (sockaddr*)&server, serverLength);
memset(buf, 0, sizeof(buf));
int bytesIn = recvfrom(out1, buf, 1444, 0, (sockaddr*)&server, &serverLength);
if (bytesIn > 0)
{
cout << "Image Received :" << bytesIn <<packet_counter << endl;
packet_counter++;
}
else
{
cout << "Not Received : " << endl;
}
}
WSACleanup();
}
//***** Function to Send Bytes to the Camera *****//
void _sendPacket(SOCKET sock, const char* s, int len, int i)
{
int sendOk = sendto(sock, (const char*)s, len, 0, (sockaddr*)&server, sizeof(server));
if (sendOk == SOCKET_ERROR)
{
cout << "Didn't Work" << WSAGetLastError() << endl;
}
else
{
cout << "\nSend Succesfully" << " " << i << endl;
}
char buf[2000];
int serverLength = sizeof(server);
int bytesIn = recvfrom(sock, buf, 2000, 0, (sockaddr*)&server, &serverLength);
if (bytesIn > 0)
{
cout << "Message Received :" << bytesIn << endl;
}
}
//***** Function to call the _sendPacket function and send commands to the Camera *****//
void _packetConfig(SOCKET sock)
{
// 59 Commands and every command call _snedPacket function to send commands to camera it will working properly
}
In the above code I have to first send this 59 commands written in _packetConfig function then only camera will send Image packets I am receiving the reply of all that commands.
When I run wireshark also with that code I can see that after these 59 commands
the camera is giving 3580*51 packets.i.e 51 frames and each frame contain 3580 packets
Thank you for posting your code. There are actually a few things wrong with it so first I will post some code that works as a reference and then mention the major issues I noticed with yours afterwards.
OK, here is some code that works for me:
#include <WinSock2.h> // ** before** windows.h
#include <WS2tcpip.h>
#include <iostream>
#include <stdio.h>
#include <Windows.h>
#include <assert.h>
#pragma comment (lib, "ws2_32.lib")
const int port = 3956;
// main
int main (char argc, char* argv[])
{
WSADATA wsadata;
WORD version = MAKEWORD(2, 2);
int err = WSAStartup (MAKEWORD (2, 2), &wsadata);
if (err)
{
std::cout << "WSAStartup failed, error: " << err << std::endl;
return 255;
}
char buf [1444];
bool send = argc > 1 && _stricmp (argv [1], "send") == 0;
if (send)
{
// Send
SOCKET skt_out = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
assert (skt_out != INVALID_SOCKET);
sockaddr_in destination_address = { };
destination_address.sin_family = AF_INET;
destination_address.sin_port = htons (port);
inet_pton (AF_INET, "192.168.1.2", &destination_address.sin_addr);
memset (buf, 'Q', sizeof (buf));
printf ("Sending: ");
for ( ; ; )
{
sendto (skt_out, buf, sizeof (buf), 0, (const sockaddr *) &destination_address, sizeof (destination_address));
printf (".");
Sleep (50);
}
closesocket (skt_out);
WSACleanup ();
return 0;
}
// Receive
SOCKET skt_in = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
assert (skt_in != INVALID_SOCKET);
int receive_buffer_size = 65536;
if ((setsockopt (skt_in, SOL_SOCKET, SO_RCVBUF, (const char *) &receive_buffer_size, sizeof (int)) ) < 0)
std::cout << "Could not set SO_RCVBUF, error: " << WSAGetLastError () << std::endl;
sockaddr_in receive_address = { };
receive_address.sin_family = AF_INET;
receive_address.sin_port = htons (port);
receive_address.sin_addr.s_addr = htonl (INADDR_ANY);
if (bind (skt_in, (const sockaddr *) &receive_address, sizeof (receive_address)) == -1)
{
std::cout << "bind failed , error: " << WSAGetLastError () << std::endl;
return 255;
}
int packetCounter = 0;
printf ("Receiving: ");
for ( ; ; )
{
int bytesIn = recvfrom (skt_in, buf, sizeof (buf), 0, NULL, 0);
if (bytesIn > 0)
std::cout << "Packet received:" << bytesIn << " bytes (" << ++packetCounter << ")" << std::endl;
else
std::cout << "Receive error: " << WSAGetLastError () << std::endl;
}
closesocket (skt_in);
WSACleanup ();
return 0;
}
To run this in 'send' mode, specify send as the first argument on the command line. Otherwise it acts as a receiver (aka server).
So what's wrong with your code? Well, in no particular order:
as we already said, you shouldn't be using SOCK_RAW
you need to call bind on the receiving socket so that it knows what port to listen on. The sockaddr *from parameter to recvfrom doesn't mean what you think it means (please check the docs). You will see I pass this as NULL.
you were misinterpreting the return value from WSAStartup. Again, please check the docs.
But having said all that, it was essentially the call to bind that you were missing. I rewrote the code because yours is rather messy.
Also, important detail, UDP doesn't guarantee delivery - there are a number of reasons why a packet that has been sent does not get received or might even get received out of sequence (does your camera sequence the packets in some way?)
You need to cater for that in the logic of your application (and it that's a problem, it's better to use TCP, which does guarantee packet delivery and sequencing).
I am able to make client and server connect, but not chat with each other. I can only make the server receive messages and the client can only to send them...but it doesn't work the other way around.
Relevant server code:
while(recv(acceptedSocket,buffer,255,0)){
std::cout << buffer << std::endl;
memset(buffer,0,sizeof(buffer));
n = send(acceptedSocket,"Message received!", 18 , 0);
if(n < 0)
error("Failed sending data!");
}
Relevant client code:
do{
memset(buffer,0,sizeof(buffer));
std::cout << "Enter your message: " << std::endl;
std::cin.getline(buffer,255);
n = send(connectingSocket,buffer,strlen(buffer),0);
} while(n > 0);
Can I make server and client send and receive messages without multi-threading or do I have to multi-thread?
All code
Server:
int main() {
int listeningSocket,acceptedSocket,port,n;
unsigned int clientLength;
char buffer[256];
struct sockaddr_in server_address , client_address;
std::cout << "ENTER PORT(ABOVE 2000):";
std::cin >> port;
if(port < 2000){
error("NO PORT PROVIDED");
}
listeningSocket = socket(AF_INET,SOCK_STREAM,0);
if(listeningSocket < 0)
error("FAILED CREATING A SOCKET!");
memset((char * ) &server_address,0,sizeof(server_address));
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = INADDR_ANY;
server_address.sin_port = htons(port);
if(bind(listeningSocket,(struct sockaddr *) &server_address,sizeof(server_address)) < 0)
error("BINDING FAILED!");
listen(listeningSocket,5);
clientLength = sizeof(client_address);
acceptedSocket = accept(listeningSocket,(struct sockaddr *) &client_address,&clientLength);
if(acceptedSocket < 0)
error("ACCEPTING FAILED!");
std::cout << "Connection incoming from " << client_address.sin_addr.s_addr << std::endl;
while(recv(acceptedSocket,buffer,255,0)){
std::cout << buffer << std::endl;
memset(buffer,0,sizeof(buffer));
n = send(acceptedSocket,"Message received!", 18 , 0);
if(n < 0)
error("Failed sending data!");
}
}
Client:
int main() {
int connectingSocket,portNo,n;
struct sockaddr_in server_address;
struct hostent *server;
char buffer[256];
std::cout << "Enter server's IP:";
char * ipHolder;
std::cin >> ipHolder;
server = gethostbyname(ipHolder);
if(server == NULL){
error("NO SUCH HOST!");
}
std::cout << "ENTER PORT:";
std::cin >> portNo;
connectingSocket = socket(AF_INET,SOCK_STREAM,0);
if(connectingSocket < 0)
error("FAILED OPENING A SOCKET!");
memset(&server_address,0,sizeof(server_address));
server_address.sin_family = AF_INET;
server_address.sin_port = htons(portNo);
memcpy(server->h_addr_list,&server_address.sin_addr.s_addr,server->h_length);
if(connect(connectingSocket,(sockaddr *)&server_address,sizeof(server_address)) < 0)
error("CONNECTION FAILURE!");
std::cout << "CONNECTION MADE!" << std::endl;
std::cin.ignore();
do{
memset(buffer,0,sizeof(buffer));
std::cout << "Enter your message: " << std::endl;
std::cin.getline(buffer,255);
n = send(connectingSocket,buffer,strlen(buffer),0);
}while(n > 0);
return 0;
}
Thank you!
The easiest most straight-forward solution is making the server/client send a message and right after that make it wait for a reply from the other, like that:
server:
while(recv(acceptedSocket,buffer,255,0)){ //here you read a message
std::cout << "clients message: " << buffer << std::endl; //print it on screen
memset(buffer,0,sizeof(buffer));
/*
instead of sending "message recieved" to server, try to get
some message from the user using cin maybe
and send() what the user has entered
then loop over and get another message
*/
std::cin.getline(buffer,255); //get user's message
//don't forget to find out buffer length
n = send(acceptedSocket, buffer, buffer_len , 0); //send the message
if(n < 0)
error("Failed sending data!");
//client has got the message now, you loop and wait for his reply
}
client:
do{
memset(buffer,0,sizeof(buffer));
std::cout << "Enter your message: " << std::endl;
std::cin.getline(buffer,255); //get message
n = send(connectingSocket,buffer,strlen(buffer),0); //send it to server
/*
recv() from the connecting socket and print the message
when you loop over, the server has your message, user enters
another one, and the client waits for the message, and then
sends something the user entered
*/
recv(connectingSocket,buffer,255,0); //wait for server's user reply
std::cout << "server's message: " << buffer << std::endl;
//you have now recieved server's message, you loop over and you're ready to send his another one
} while(n > 0);
So like this, you have to wait for a reply, you cannot send 2(+) messages i a row.
I have not tested this, but it's a rough idea of what it might look like :)
I did two different programs and it works on same computer or different ones on the network...
Have fun... this is what I started with... looking at yours, there are a number of concerns... so cut and past and play with this server and client.
//Echo Server and Client using Berkley Socket Primitives
// Server
#include <sys/socket.h>
#include <netinet/in.h>
int main (int argc, const char * argv[]) {
char buffer[128];
int sinlen;
struct sockaddr_in sin;
int s, h;
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons(888); // Port 888
// SOCK_STREAM is TCP
s = socket(AF_INET, SOCK_STREAM,0);
// Bind socket to local port
bind(s,(struct sockaddr*)&sin,sizeof(sin));
// Listen for 1 connection
listen(s,1);
sinlen = sizeof(sin);
// 1. Block for connection
h=accept(s,(struct sockaddr*)&sin,&sinlen );
// 2. Block for receive
recv(h,buffer,sizeof(buffer),0);
// 3. Echo received data
send(h,buffer,strlen(buffer),0);
close(h);
return 0;
}
// Client
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
int main (int argc, const char * argv[]) {
char buffer[128]= "Hello world";
struct sockaddr_in sin;
struct hostent *host;
int s;
host = gethostbyname("localhost");
memcpy(&(sin.sin_addr), host->h_addr,host->h_length);
sin.sin_family = host->h_addrtype;
sin.sin_port = htons(888);
// Create socket port 888
s = socket(AF_INET, SOCK_STREAM,0);
// 1. Block for server accept
connect(s, (struct sockaddr*)&sin,sizeof(sin));
// 2. Send "Hello world"
send(s,buffer,strlen(buffer)+1,0);
// 3. Block for receive
recv(s,buffer,sizeof(buffer),0);
// Print received data
NSLog(#"Received %s\n",buffer);
close(s);
return 0;
}
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`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