I use to code in Python. Now I'm trying C++. When I run the program I see the target address (w/ Wireshark) reverse, even if I use htonl. In Python this same program worked fine.
Follow the code. At the bottom I printed the result.
I'm using Ubuntu 12.04LTS and g++ (Ubuntu/Linaro 4.6.3).
//UdpClient.cpp
#include <iostream>
#include <string>
#include <sstream>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <cstdlib>
#include <arpa/inet.h>
#include <typeinfo>
using namespace std;
int main(int argc, char* argv[])
{
int s, p, rb,rs;
int bytesend;
char buf[1024];
int len;
char ent[16];
char Porta[5];
unsigned long EndServ;
struct sockaddr_in UdpServer, UdpClient;
int UdpServerLen = sizeof(UdpServer);
//do text
string msg("The quick brown fox jumps over the lazy dog\n");
len = msg.copy(buf, msg.size(), 0);
buf[len] = '\0';
//do socket
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s == -1){
cout << "No socket done\n";
}
else {
cout << "Socket done\n";
}
//populate UdpClient struct
UdpClient.sin_family = AF_INET;
UdpClient.sin_addr.s_addr = INADDR_ANY;
UdpClient.sin_port = 0;
//populate UdpServer struct
UdpServer.sin_family = AF_INET;
UdpServer.sin_addr.s_addr = inet_addr(argv[1]);
//check if addres is correct
cout << "ServerAddress: " << hex << UdpServer.sin_addr.s_addr << endl;
UdpServer.sin_port = htons(atoi(argv[2]));
//bind socket
rb = bind(s, (struct sockaddr *)&UdpClient, sizeof(UdpClient));
if (rb == 0){
cout << "Bind OK!\n";
}
else {
cout << "Bind NOK!!!\n";
close(s);
exit(1);
}
//send text to Server
cout << "UdpServSiz: " << sizeof(UdpServer) << endl;
rs = sendto(s, buf, 1024, 0, (struct sockaddr *)&UdpServer, sizeof(UdpServer));
if (rs == -1){
cout << "Message NOT sent!!!\n";
}
else {
cout << "Message SENT!!!\n";
}
close(s);
return 0;
}
/*
edison#edison-AO532h:~/CmmPGMs$ ./UdpClient 127.0.0.1 6789
Socket done
ServerAddress: 100007f (using htonl or not!!)
Bind OK!
Message SENT!!!
edison#edison-AO532h:~/CmmPGMs$
*/
Sounds like you're on ARM (Linaro)? In which case the endianness of the processor matches network order, so htonl and ntohl basically do nothing.
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 using libev + non-blocking sockets to send a request to a server. I'm using Keep Alive because I need to send future requests to the destination over this same connection.
Behavior
Run the program and it fetches the URL and logs to console, as expected.
After doing this, wait and don't push ctrl+c to exit the program.
Expected
App should stay open because event loop is waiting for future responses but should not console log anything after the initial response.
Actual
Leave the app running. After 30+ seconds, it will start to console log the same response over and over and over again without end.
Question
Why is libev calling my callback (example_cb) repeatedly when no new request was sent and no new response data was received? How can I fix this?
#include <ev.h>
#include <stdio.h>
#include <iostream>
#include <ctype.h>
#include <cstring>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <unistd.h>
#include <sstream>
#include <fstream>
#include <string>
using namespace std;
void sendRequest(int sockfd)
{
puts("------");
puts("sendRequest() was called");
stringstream ss;
ss << "GET /posts/11 HTTP/1.1\r\n"
<< "Host: jsonplaceholder.typicode.com\r\n"
<< "Accept: application/json\r\n"
<< "\r\n";
string request = ss.str();
if (send(sockfd, request.c_str(), request.length(), 0) != (int)request.length()) {
cout << "Error sending request." << endl;
exit(1);
}
cout << "Request sent. No err occured." << endl;
}
static void delay_cb(EV_P_ ev_timer *w, int revents)
{
puts("------");
puts("delay_cb() was called");
sendRequest(3);
}
static void example_cb(EV_P_ ev_io *w, int revents)
{
puts("------");
puts("example_cb() was called");
int sockfd = 3;
size_t len = 80*1024, nparsed; // response must be <= 80 Kb
char buf[len];
ssize_t recved;
recved = recv(sockfd, &buf, len, 0);
if (recved < 0) {
perror("recved was <1");
}
// don't process keep alives
if (buf[0] != '\0') {
std::cout << buf << std::endl;
}
// clear buf
buf[0] = '\0';
std::cout << "buf after clear attempt: " << buf << std::endl;
}
int example_request()
{
std::string hostname = "jsonplaceholder.typicode.com";
int PORT = 80;
struct sockaddr_in client;
struct hostent * host = gethostbyname(hostname.c_str());
if (host == NULL || host->h_addr == NULL) {
cout << "Error retrieving DNS information." << endl;
exit(1);
}
bzero(&client, sizeof(client));
client.sin_family = AF_INET;
client.sin_port = htons( PORT );
memcpy(&client.sin_addr, host->h_addr, host->h_length);
// create a socket
int sockfd = socket(PF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
cout << "Error creating socket." << endl;
exit(1);
}
cout << "Socket created" << endl;
// enable keep alive
int val = 1;
setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof val);
if (connect(sockfd, (struct sockaddr *)&client, sizeof(client)) < 0) {
close(sockfd);
cout << "Could not connect" << endl;
exit(1);
}
cout << "Socket connected" << endl;
// make non-blocking
int status = fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL, 0) | O_NONBLOCK);
if (status == -1) {
perror("ERROR making socket non-blocking");
}
std::cout << "Socket set to non-blocking" << std::endl;
std::cout << "Sockfd is: " << sockfd << std::endl;
return sockfd;
}
int main(void)
{
// establish socket connection
int sockfd = example_request();
struct ev_loop *loop = EV_DEFAULT;
ev_io example_watcher;
ev_io_init(&example_watcher, example_cb, sockfd, EV_READ);
ev_io_start(loop, &example_watcher);
// used to send the request 2 sec later
ev_timer delay_watcher;
ev_timer_init(&delay_watcher, delay_cb, 2, 0.0);
ev_timer_start(loop, &delay_watcher);
ev_run(loop, 0);
return 0;
}
Edit: Code updated with suggestions from comments
The source of the problem is that you do not check recved == 0 condition which corresponds to the other side closing the connection. When that happens the OS sets the socket into "closed mode" which (at least under linux) is always ready for reading and subsequent calls to recv will always return 0.
So what you need to do is to check for that condition, call close(fd); on the file descriptor (possibly with shutdown before) and ev_io_stop on the associated watcher. If you wish to continue at that point then you have to open a new socket and eo_io_start new watcher.
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 wrote a simple client program in Visual C++ 2010 which connects to a client using winsock. When I try to run this program on another computer, it complains about missing Net Framework.
I wonder why that would be the case? What's in my code that requires net framework?
The error message:
application, you must first install one of the following versions of
the .NET Framework v4.0...etc
Here's my code
#pragma once
#pragma comment(lib, "Ws2_32.lib")
#include "stdafx.h"
#include <sdkddkver.h>
#include <WinSock2.h>
#include <Windows.h>
#include <iostream>
#include <string>
#include <time.h>
#include <cstring>
#include <sstream>
#define SCK_VERSION2 0x020
using namespace std;
void main() {
long Successful;
WSAData WinSockData;
WORD DLLVersion;
DLLVersion = MAKEWORD(2,1);
Successful = WSAStartup(DLLVersion, &WinSockData);
int sd,rcv,i,myint = 1;
hostent *host = gethostbyname("localhost");
char * myhostadd = inet_ntoa (*((struct in_addr *) host->h_addr_list[0]));
string memzi2,memzi,Converter;
char Message[200],tell[200] = "haa";
SOCKADDR_IN Address;
SOCKET sock;
sock = socket(AF_INET,SOCK_STREAM,NULL);
Address.sin_addr.s_addr = inet_addr(myhostadd);
Address.sin_family = AF_INET;
Address.sin_port = htons(7177);
cout << "Connecting to server...";
Successful = connect(sock, (SOCKADDR*)&Address, sizeof(Address));
u_long iMode=1;
ioctlsocket(sock,FIONBIO,&iMode);
if (Successful == 0) {
cout << "Connected. "<< endl;
for (;;++i) {
std::stringstream convert2;
convert2 << myint;
memzi2 = convert2.str();
std::cout << "Client: " << memzi2 << std::endl;
const char * c = memzi2.c_str();
sd = send(sock, c, sizeof(tell), NULL);
cout << "Server: ";
rcv = recv(sock,Message,sizeof(Message),NULL);
Converter = Message;
cout << Converter << endl;
std::stringstream convert1(Converter);
convert1 >> myint;
if (myint > 5000) {
myint = 1;
}
++myint;
}
closesocket(sock);
}
else cout << "Failed." << endl;
cout << "\n\n\t";
system("pause");
exit(1);
}
Thanks in advance!
Can be a simple reason, it will be using C++ CLI, i.e. common language runtime. Go to project properties and fix it up, it will not show any more.
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;