C++ Program with connect to FTP directory - c++

I trying to create some program with connection to some FTP address.
I have only basic elements on this moment and now I stopped at FTP connection.
What should I do to connect to my FTP address ?
Someone maybe have some template with code ?

You may see the code here. It is just how to connect to the server, and it use the default port 21. It passes IP address as a char*.
#include &ltnetinet/in.h>
#include &ltsys/socket.h>
#include &ltnetinet/in.h>
#include &ltarpa/inet.h>
int CFTP::ftp_connect(const char* ip)
{
m_sockctrl = socket(AF_INET,SOCK_STREAM,0);
if(0==m_sockctrl)return -1;
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(21);
addr.sin_addr.s_addr = inet_addr(ip);
int err = connect(m_sockctrl,(sockaddr*)&addr,sizeof(addr));
if(err)return -1;
err = ftp_checkresp('2');
if(err)return -1;
return 0;
}

Related

binding errors: "cannot assign requested address" and "permission denied" [duplicate]

Following code is TCP server program just send back “HELLO!!” to client.
When I run server with port 80, bind() is returned Permission denied.
Port 12345 is OK.
How can I use port 80 for this server program?
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int
main(){
int sock0;
struct sockaddr_in addr;
struct sockaddr_in client;
int len;
int sock;
char *message;
message = "HELLO !!";
sock0 = socket(AF_INET,SOCK_STREAM,0);
addr.sin_family = AF_INET;
addr.sin_port = htons(80);
inet_pton(AF_INET,"127.0.0.1",&addr,sizeof(addr));
bind(sock0,(struct sockaddr *)&addr,sizeof(addr));
perror("bind");
len = sizeof(client);
sock = accept(sock0,(struct sockaddr *)&client,&len);
perror("accept");
write(sock,message,sizeof(message));
perror("write");
close(sock);
return 0;
}
Ports below 1024 are considered "privileged" and can only be bound to with an equally privileged user (read: root).
Anything above and including 1024 is "free to use" by anyone.
OT: you may know this already, but the port in your example is that for HTTP web servers. Anything listening to this port should speak HTTP, too. A simple "hello world" does not suffice. ;-)
Only the root user is allowed to bind to ports <= 1024. Every ports > 1024 can be bound to by normal users.
Try executing your program as root or with sudo.
you have to run your application with super user account (root)
Run your application with sudo command

Why is this program timing out without any network traffic?

I am trying to create a simple c++ program that hides the differences between Linux and Windows when making sockets and connecting to servers
The Linux part of this code compiles without any warnings or errors but times out after resolving the host IP and does not connect to the server running (nc -lvnp 7777)
Using tcpdump -i eth0 -v port 7777 to capture all the traffic to and from the machine running the program shows nothing
class Socket
{
public:
int initsoc(void);
int connectsoc(int sock, const char * host, int port);
};
int Socket::connectsoc(int sock, const char * host, int port)
#ifdef _WIN32
/* windows part */
#else
struct hostent *server;
struct sockaddr_in server_addr;
struct in_addr *address;
server_addr.sin_family = AF_INET;
server_addr.sin_port = port;
/* resolve host */
server = gethostbyname(host);
if (server == NULL)
{
printf("Error : %s \nFailed to resolve %s:%d", strerror(errno), host, port);
return -1;
}
address = (struct in_addr *) (server->h_addr);
printf("Resolved: [%s] ===> [%s]\n", host, inet_ntoa(*address));
server_addr.sin_addr.s_addr = inet_addr(inet_ntoa(*address));
iResult = connect(sock, (struct sockaddr*)&server_addr, sizeof(server_addr));
printf("Connect returned : %d\n",iResult);
if (iResult < 0)
{
printf("Error: %s\nFailed to connect\n",strerror(errno));
return -1;
}
printf("Connected to [%s:%d]\n",host,port);
return 0;
I tried to open a netcat listener on a machine on the same network as the computer running the program without any NATs but it still times out
this is how i compiled and what it outputs
g++ -Wall -ggdb3 -pedantic -g main.cpp -o app
Resolved: [10.0.0.100] ===> [10.0.0.100]
Connect returned : -1
Error: Connection timed out
Failed to connect
the ip of the machine running the code is 10.0.0.2
the ip of the machine running the netcat server is 10.0.0.100
As commented by #user253751, this line:
server_addr.sin_port = port;
should be changed to:
server_addr.sin_port = htons(port);

WinSock2: connect() delivers 'connection refused'

I have been trying to get a simple SFTP program working with code from this website, but I have not been able to get it to even send out data without it returning error code 10061 (WSAECONNREFUSED). I have tried using Wireshark on the active interface with all firewalls disabled, but it didn't say anything was being sent to the address I gave (ex: 72.196.212.127). However, when I give it a local address like 192.168.1.101, it gives error code 10060 (WSAETIMEDOUT), still not sending out any data on the network. I am able to connect to the target machine on both address with software like Putty and WinSCP and ping it on the command prompt.
Here is the relevant part of my connection method:
// Open socket
WSADATA data;
int err = WSAStartup(MAKEWORD(2, 0), &data);
if (err != 0) return "ERROR: Failed to initialize WSA";
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
sin.sin_addr.s_addr = to_uint32_t(ip);
if (net::connect(sock, (struct sockaddr*) &sin, sizeof(struct sockaddr_in)) != 0) return "ERROR: Could not connect to host. Code: " + std::to_string(WSAGetLastError());
The variable port is an integer (value = 22), with ip being a string (192.168.1.101 or 72.196.212.127). This function returns the "Could not connect to host" error. No other errors occur.
Here is the to_uint32_t method:
std::uint32_t to_uint32_t(const std::string& ip_address)
{
const unsigned bits_per_term = 8;
const unsigned num_terms = 4;
std::istringstream ip(ip_address);
uint32_t packed = 0;
for (unsigned i = 0; i < num_terms; ++i)
{
unsigned term;
ip >> term;
ip.ignore();
packed += term << (bits_per_term * (num_terms - i - 1));
}
return packed;
}
#selbie pointed out that I was not using the correct function for resolving the IP. To fix my code, I just switched sin.sin_addr.s_addr = to_uint32_t(ip); to inet_pton(AF_INET, ip, &sin.sin_addr);.

Connection refused while trying to retrieve html from http website using sockets in C

I have made a pretty simple http client which would retrieve html from http website and print it. But there seems to be some problem while using connect() function.Using perror() I found that it is giving connection refused error.
This is my code
#include <string.h>
#include <stdio.h>
#include <iostream>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
char *address;
address = argv[1];
int c_socket = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in URLaddress;
URLaddress.sin_family = AF_INET;
URLaddress.sin_port = htons(80);
inet_pton(0,address,&URLaddress.sin_addr.s_addr);
int con = connect(c_socket, (struct sockaddr*) &URLaddress,
sizeof(URLaddress));
perror("error");
return 0;
}
This is the input
151.101.13.5
This is the output
error: Connection refused
I am passing IP of website as input.
I have seen all other similar questions but didn't get any answer as how to fix this because this keeps happening with every website I try my program with.
Please tell how to resolve this.
The following version of the code works on Windows/MSC:
int test(void)
{
char *address;
int c_socket, con;
struct sockaddr_in URLaddress;
char request[] = "GET / HTTP/1.1\r\n\r\n";
char response[4096];
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD( 2, 2 );
address = "151.101.13.5";
if (WSAStartup (wVersionRequested, &wsaData)!= 0) {
printf("DLL not found\n");
return -1;
}
if ((c_socket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET ) {
printf("socket error: %d\n", WSAGetLastError());
return -1;
}
URLaddress.sin_family = AF_INET;
URLaddress.sin_port = htons(80);
URLaddress.sin_addr.s_addr= inet_addr(address);
con = connect(c_socket, (struct sockaddr*) &URLaddress, sizeof(URLaddress));
send(c_socket, request, strlen(request), 0);
recv(c_socket, response, sizeof(response), 0);
WSACleanup();
printf ("%s\n",response);
return 0;
}
The repsonse is:
<title>Fastly error: unknown domain </title>
</head>
<body>
<p>Fastly error: unknown domain: . Please check that this domain has been added to a service.</p>
<p>Details: cache-fra19128-FRA</p></body></html>5¸`¡qu
inet_pton(3) requires a first parameter to specify the address family and you have passed 0 for it (which is not the same as AF_INET), and you had to pass AF_INET, in accordance of the protocol family you are using.
inet_pton(3) is a protocol family independent conversion routine, but it needs to know what is the actual used to be able to convert addresses properly.
By the way, is a server listening on the requested address and port? have you tested that a browser is capable of getting something from that address before running your program?

Calling socket::connect, socket::bind, socket::listen without using getaddrinfo( ) function before it

In all the example including Beej's Guide, the IP address is provided in dot notation and then it's fed to ::getaddrinfo(). This post doesn't answer my question.
After which the addrinfo struct is used for socket related functions (e.g. connect(), bind(), listen()). For example:
struct addrinfo hints, *res;
// ... create socket etc.
connect(sockfd, res->ai_addr, res->ai_addrlen);
Example
The variable ai_addr is of type sockaddr which can be safely typecasted to sockaddr_storage, sockaddr_in and sockaddr_in6.
Question:
If I typecast sockaddr to sockaddr_in (or sockaddr_in6)
sockaddr_in& ipv4 = (sockaddr_in&)(sockaddr_variable);
and feed below info:
ipv4.sin_family = AF_INET
ipv4.sin_addr = [IP Address in net byte order]
ipv4.sin_port = [Port number in net byte order]
Can I call the connect() method directly using above info?
connect(sockfd, &ipv4, sizeof(ipv4));
With my program it doesn't appear to work. Am I missing something, or is there a better way?
The motivation behind is that, if we have the information of IPAddress, Port etc. in socket readable format then why to go through the cycle of getaddrinfo()
Be sure you're placing your values in network order, here's a small example:
#include<stdio.h>
#include<sys/socket.h>
#include<arpa/inet.h>
int main(int argc, char *argv[])
{
int sock;
struct sockaddr_in server;
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1)
{
printf("Could not create socket\n");
}
printf("Socket created\n");
server.sin_family = AF_INET;
// 173.194.32.207 is a google address
server.sin_addr.s_addr = 173 | 194 << 8 | 32 << 16 | 207 << 24;
server.sin_port = 0x5000; // port 80
if (connect(sock, (struct sockaddr *)&server, sizeof(server)) < 0)
{
perror("connect failed. Error");
return 1;
}
printf("Connected\n");
close(sock);
return 0;
}
First check whether the machine is reachable & the server application is running on the machine using "netstat" utility. Use inet_aton method to convert dotted address to network byte order. Finally, log the error value returned by the connect to get the exact reason of failure.
It's worth noting that calling socket::{connect, bind, ...} is wrong: these are C APIs and C doesn't have namespaces, classes and so on.
You should use getaddrinfo as it's much easier and safer to use. But nothing prevents you from using struct sockaddr and all its variants. Indeed, getaddrinfo is a sort of wrapper as stated in man(3) getaddrinfo:
The getaddrinfo() function combines the functionality
provided by the gethostbyname(3) and getservbyname(3) functions into a
single interface, but unlike the latter functions, getaddrinfo() is
reentrant and allows programs to eliminate IPv4-versus-IPv6 dependen‐
cies.
An example:
#include <sys/socket.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main()
{
struct sockaddr_in addr = {0};
addr.sin_family = AF_INET;
addr.sin_port = htons(80);
inet_pton(addr.sin_family, "198.252.206.16", &addr.sin_addr);
int fd = socket(addr.sin_family, SOCK_STREAM, 0);
if (fd == -1)
; /* could not create socket */
if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
; /* could not connect */
close(fd);
}