#include <sys/socket.h>
#include <cstdio>
#include <stdlib.h>
#include <iostream>
#include <errno.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#define BUFSIZE 5000
#define PORT 80
using namespace std;
int main(int argc, char* argv[]){
char buffer[BUFSIZE];
int sockfd;
struct sockaddr_in their_addr;
if((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1){
perror("Socket generating failed");
exit(1);
}
their_addr.sin_family = AF_INET;
their_addr.sin_port = htons(PORT);
their_addr.sin_addr.s_addr = htonl(((struct in_addr*)gethostbyname("www.google.com")->h_addr_list[0])->s_addr);
if(connect(sockfd, (struct sockaddr*)&their_addr, sizeof(struct sockaddr)) == -1){ // stops at here!
perror("Connection failed");
exit(1);
}
close(sockfd);
return 0;
As a test of a combination of gethostbyname + connect, I wrote a simple code.
It queries the IP address of google by means of gethostbyname(), connects to google do nothing, and close the socket.
However, the program just stops at a line of the connect() function without any error including perror().
How can I fix this?
Get the s_addr, make sure it is an ipv4 address, and then on the command line try to ping that address with the command 'ping addr'
After that you could try a program like nmap but most likely ping will be enough.
There is probably nothing wrong with your code. You need to see if there is a proxy or firewall or anything else interfering with your network connection. You will also want to confirm you are getting an ipv4 address with gethostbyname
I solved this problem by removing htonl. I don't know why, and what could happen in future as a result of removing it. But this would be my best.
The socket API is not part of C++, it is posix. gethostbyname()is obsolete, use getaddrinfo instead. Read the appropriate man page, it also contains as example precisely the code you look for...
Related
I try to send hex data to another device. The compilation does not lead to errors. But when I launch the function from the terminal nothing happens but a light should turn on. I put a cout on connect () to see if I have some connection problems but it answers 0 (so I have no problems) maybe it's how I write the hex code?
Besides the code I also insert the command line that I execute with the Hex code. The strange thing is that if I use any program like PacketSender with the same parameters it works.
./main 192.168.2.170 26810000A7
in attachment I also add the screenshot made on PacketSender.In addition what I can say is that if I leave the recv () command in the code once I give the command from the terminal the prompt remains pending ... if instead I comment the recv () once I give the command from the prompt it returns to the prompt but without doing anything (so without turning on the light). Does anyone have any ideas?
enter image description here
#include <stdio.h>
#include <errno.h>
#include <string>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <cstring>
#include <unistd.h>
#include <iostream>
#include <unistd.h>
using namespace std;
// per compilare gcc connect_PE.cpp -lstdc++ -o main
int main(int argc, char *argv[])
{
int sockfd, n;
struct sockaddr_in servaddr;
std::string serveraddr = argv[1];
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr(serveraddr.c_str());
servaddr.sin_port = htons(9761);
connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
cout << connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
const std::string hex = argv[2];
char *number = strcpy(new char[hex.length() + 1], hex.c_str());
send(sockfd, &number, 8, 0);
recv(sockfd, &number, 8, 0);
}
You’re passing the address of number when you should be passing its value.
Or even better, just pass hex.data() or &hex[0] – there’s no point in copying it.
Also note that you are sending a string of characters, not numbers in hexadecimal form.
(The first char is not 0x26 - that is, 38 - but ’2’, wich is probably 50.)
If you want to send the corresponding numbers, you need to convert the input first.
Sockets work very poorly with everything that is not char*, so it is better to immediately send a string from the terminal argument, and perform all the necessary transformations on the server.
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?
I am trying to write a program for my raspberry pi that changes its system time to the time from a GPS unit on the same network. The GPS sends out a 72 byte UDP packet across port 3000. I am new to socket programming so I am unsure where I am going wrong.
The trouble that I am having is that I can't seem to get it to build with g++. I am getting the following error:
So the main error seems to be in the line
char A = struct sockaddr_in address;
Here is the start of my program and the method where I create the socket and where the error is located, if you would like the main method of my program then I will add it too.
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include <errno.h>
#include <math.h>
// defines the socket used by the GPS
#define PORT 3000
/****************************/
int CreateSocket(int port)
/****************************/
{
// Create an UDP-socket
int sock = socket(AF_INET, SOCK_DGRAM, 0);
// Check if UDP-socket was created
if(sock==-1)
{
fprintf(stderr, "1CreateSocket: socket failed\n");
return -1;
}
// Bind it to the local IP-address
struct sockaddr_in address;
char A = struct sockaddr_in address;
fprintf(stderr, A);
// Pointer to the block of memory to fill with address data
memset(&address, 0, sizeof(address));
address.sin_family = AF_INET; // Address family for IP-address
address.sin_addr.s_addr = htonl(INADDR_ANY); // converts the unsigned integer hostlong from host byte order to network byte order
address.sin_port = htons(port); // converts the unsigned short integer hostshort from host byte order to network byte order
// Check if IP-address is correct, if not Socket failed. Otherwise it returns the socket
if(bind(sock, (struct sockaddr *) &address, sizeof(address))==-1)
{
fprintf(stderr, "2CreateSocket: bind failed\n");
close(sock);
return -1;
}
return sock;
}
Can anyone see any obvious errors here? Thanks
You don't really need these two lines:
char A = struct sockaddr_in address;
fprintf(stderr, A);
You can delete them, since they don't do anything useful, and they have a syntax error.
And to do some extra cleanup, the comment of the binding above those lines that can be deleted should actually go above the call to bind().
Below is the following basic socket code I came up with:
//General includes:
#include <iostream>
#include <stdio.h>
#include <string>
//Network related includes:
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
//Target host details:
#define PORT 1234
#define HOST "74.74.74.74"
using namespace std;
//Function prototypes:
string MessageFormat(int, char**);
void MessageSend(string);
int main(int argc, char *argv[])
{
//Parse arguments and format message:
string message = MessageFormat(argc, argv);
//Send the message out:
MessageSend(message);
return 0;
}
string MessageFormat(int argc, char *argv[])
{
//Massage the command line parameters
// into my desired payload format.
return message;
}
void MessageSend(string message)
{
int sd, ret;
struct sockaddr_in server;
struct in_addr ipv4addr;
struct hostent *hp;
sd = socket(AF_INET,SOCK_DGRAM,0);
server.sin_family = AF_INET;
inet_pton(AF_INET, HOST, &ipv4addr);
hp = gethostbyaddr(&ipv4addr, sizeof ipv4addr, AF_INET);
//hp = gethostbyname(HOST);
bcopy(hp->h_addr, &(server.sin_addr.s_addr), hp->h_length);
server.sin_port = htons(PORT);
connect(sd, (const sockaddr *)&server, sizeof(server));
send(sd, (char *)message.c_str(), strlen((char *)message.c_str()), 0);
}
This is quite basic, and does in fact work. HOWEVER, it's sending UDP packets instead of TCP packets, so the target host expecting TCP rejects these. Also, by inspecting connect/send values and watching my interfaces with ngrep I can 100% verify the packet is going out, so that's not the issue.
I'm only interested in modifying what I have, not creating a full featured server with boost asio. How can I tweak this so that it operates in terms of TCP instead of UDP?
Following are changes you need to make to transfer data via TCP
While creating socket pass correct parameters .In above example you passed SOCK_DGRAM instead pass SOCK_STREAM.
After binding server should go into listen mode (check the manual page of listen)
while Client Side should connect after socket creation.
Then accept in server side after listen.
Final Read and write to transfer data
Diagram attached will give you a clear picture of TCP connection
You can check manual pages for detailed info on all functions or refer beej's guide for socket programming ( use this link )
Replace SOCK_DGRAM with SOCK_STREAM.
Also, read the manual or get a good book.
I like to know, winapi from which i can get ipaddress using interface name. The Linux version of which is as below.
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <net/if.h>
#include <unistd.h>
#include <arpa/inet.h>
int main()
{
int fd;
struct ifreq ifr;
char iface[] = "eth0";
fd = socket(AF_INET, SOCK_DGRAM, 0);
//Type of address to retrieve - IPv4 IP address
ifr.ifr_addr.sa_family = AF_INET;
//Copy the interface name in the ifreq structure
strncpy(ifr.ifr_name , iface , IFNAMSIZ-1);
ioctl(fd, SIOCGIFADDR, &ifr);
close(fd);
//display result
printf("%s - %s\n" , iface , inet_ntoa(( (struct sockaddr_in *)&ifr.ifr_addr )->sin_addr) );
return 0;
}
I am looking similar functionality ( as code above) but for windows in C++.
may be you can tweak it to your needs...
http://kodeyard.blogspot.in/2009/09/get-ip-address-in-cwindows.html
See sample of GetAdaptersAddresses function. FriendlyName and FirstUnicastAddress are fields you need.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365915%28v=vs.85%29.aspx
See also: Get network interface name from IPv4 address
SIGAR is a cross-platform library for getting system info (CPU, RAM, DISK, and Network). It will allow you to list all network interfaces on Mac / Windows / Linux and get any other info you may need.
http://support.hyperic.com/display/SIGAR/Home
If you don't want to use the whole library, I am sure you could inspect the code to find just the piece you need.
You have to initialize WinSock first, and only then use gethostname, gethostbyname and inet_ntoa functions. The following link will help you.