I've read many examples on networking with C and I'm stuck. I can see that the TCP packets with the SYN flag are on the wire (with wireshark), but the receiving end (I've set up a virtual machine for testing purposes) sends nothing back, not even RST.
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <strings.h>
int establish_tcp(int port) {
char *ip = "10.0.2.15"; /* Virtual Machine */
struct sockaddr_in sockaddrin;
struct hostent *host;
int sock;
sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock == -1) {
fprintf(stderr, "Socket Error\n");
exit(1);
}
sockaddrin.sin_family = AF_INET;
host = gethostbyname(ip);
if(host == NULL) {
fprintf(stderr, "%s unknown host.\n", ip);
exit(2);
}
/* copies the internet address into the struct */
bcopy(host->h_addr, &sockaddrin.sin_addr, host->h_length);
/* specify port (used by TCP a layer above */
sockaddrin.sin_port = port;
/* try to connect */
return connect(sock, (struct sockaddr*) &sockaddrin, sizeof(struct sockaddr_in));
}
int main(void) {
printf("status: %i\n", establish_tcp(80));
return 0;
}
It takes a while until the packets are timed out and -1 is returned as status code. How can it happen that the target machine doesn't send a reply? What have I overlooked?
I think I've figured out that it is not a setup problem. I'm running Ubuntu 12.04. The virtual machine is a Debian Wheezy, I check its IP with ifconfig. I tried if the machine is reachable with telnet.
To escape issues which might be related to Virtual Box I tried to replace the IP with the one of Google, yielding the same results.
The problem most likely is this:
sockaddrin.sin_port = port;
The port number has to be in network byte order, which is different from the native byte order in x86 and x86_64 machines.
Change to:
sockaddrin.sin_port = htons(port);
Related
I'm trying to build a ChatBot for Twitch entirely in C Language. But i'm having problems in connecting to the server: irc.chat.twitch.tv with port 6667. I'm calling gethostbyname() to retrieve the ip address of the hostname, but the connect function never establish the connection, and returns "Connection Failed".
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#include "Authentication.h"
#include "MessageHandlers.h"
int main()
{
int sock;
struct sockaddr_in addr;
struct hostent * addr_info;
char * ip;
addr_info = gethostbyname("irc.chat.twitch.tv");
ip = inet_ntoa(*(struct in_addr *)addr_info->h_name);
printf("%s", ip);
addr.sin_family = AF_INET;
addr.sin_port = htons(6667);
addr.sin_addr.s_addr = inet_addr(ip);
sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock < 0)
{
fprintf(stderr, "\nSocket Creation Failed\n");
exit(EXIT_FAILURE);
}
printf("\nConnecting to Twitch IRC Server...\n");
if(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1)
{
fprintf(stderr, "\nConnection Failed\n");
exit(EXIT_FAILURE);
}
// SendAuthentication(sock);
/*
while(1)
{
OnMessageEvents(sock);
}
*/
exit(EXIT_SUCCESS);
}
Is there something i'm doing wrong? The twitch resolved ip address seems to be 105.114.99.45. I searched on Google for the actual ip address, but i didn't find any answers.
I used nslookup irc.chat.twitch.tv and tried all the ip addresses, but still i got "Connection Failed".
If i use telnet irc.chat.twitch.tv 6667 i get a connection and i can perform the login.
Resolved in comments above. The port number in struct sockaddr_in is in network endianness (aka big endian), while your computer is likely running as little endian. To assign it, you must use
addr.sin_port = htons(6667);
instead of
addr.sin_port = 6667;
I am hoping that this is a relatively simple answer to my question. I am attempting to learn how to program in sockets and I just can't seem to get a basic UDP example working. I am attempting to just send a string "hello" from one computer to another read it on the screen.
I started with this website
https://www.programminglogic.com/sockets-programming-in-c-using-udp-datagrams/
then tried:
https://www.abc.se/~m6695/udp.html
I have also looked at
https://www.cs.rutgers.edu/~pxk/417/notes/sockets/udp.html
but it seems that each time I try to code nothing happens. I get no errors, I just don't get any communication. I can ping my server computer from my client computer at least
My setup:
I currently have two computers one running Ubuntu 16.04 the other 14.04.
I was hoping to start off with something easy by connecting them directly. But I have tried connecting them through a switch. No success.
On the "server" computer I set up my network card to have by opening the terminal and
sudo ifconfig enps60 192.168.1.1 netmask 255.255.255.0
To create my server code in terminal I type
gedit udp_server.c
and in the text editor I type
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <ctype.h>
int main()
{
int udpSocket, nBytes;
char buffer[1024];
struct sockaddr_in serverAddr, cientAddr;
struct sockaddr_storage serverStorage;
socklen_t addr_size, client_addr_size;
/* Create UDP socket */
udpSocket = socket(AF_INET, SOCK_DGRAM, 0);
/* Configure settings in address struct */
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(0);
serverAddr.sin_addr.s_addr = inet_addr("192.168.1.1");
memset(serverAddr.sin_zero, '\0', sizeof(serverAddr.sin_zero));
/* Bind Socket */
bind(udpSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr));
printf("bind complete. Port number = %d\n", ntohs(serverAddr.sin_port));
addr_size = sizeof(serverStorage);
while(1)
{
nBytes = recvfrom(udpSocket, buffer, 1024, 0, (struct sockaddr *)%clientAddr, &addr_size);
printf("any bytes: %d\n, nBytes);
}
}
I then compile my code in terminal by typing
gcc -o udp_server udp_server.c
On my client computer (ubuntu 14.04) I open the terminal and type
sudo ifconfig eth0 192.168.1.2 netmask 255.255.255.0
then to create my client code in terminal I type
gedit udp_client.c
and in the text editor I type
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
int main()
{
int udpSocket, portNum, nBytes;
char buffer[1024] = "hello";
struct sockaddr_in serverAddr;
socklen_t addr_size;
unsigned int alen;
/*create UDP socket */
udpSocket = socket(AF_INET, SOCK_DGRAM, 0);
/* Configure settings in address struct */
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(0);
serverAddr.sin_addr.s_addr = inet_addr("192.168.1.1");
memset(serverAddr.sin_zero, '\0', sizeof(serverAddr.sin_zero));
addr_size = sizeof(serverAddr);
while(1)
{
printf("sending %s\n", buffer);
nBytes = strlen(buffer);
sendto(udpSocket, buffer, nBytes, 0, (struct sockaddr *)&serverAddr, addr_size);
sleep(1);
}
return 0;
}
I apologize if my code isn't that polished also.
Ok, well thanks guys for all the suggestions, but I do have some code that works.
I still am very unsure how any of this works, but for starters I was selecting an incorrect port number. According to Steve Summitt I checked my connection using Netcat, and when I would look at port 0 netcat would kindly let me know that I can't choose a port number that low. This is a bit confusing as everything I am reading says that port numbers start at 0. Also there is a thing about trying not to use well known ports which used to be 0-255 but is now 0-1023. I was trying to figure out if I know what ports I can use or not and I came across this.
https://sort.veritas.com/public/documents/vie/7.3/aix/productguides/html/sfcfsha_config/apgs04s03.htm
Although I am unsure the context is only when using IPv6 protocol?
Also I found this list.
https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml
I guess there are a bunch of applications on every machine that uses these ports?
The quick solution: I set the port to 1024 and forgot to bind my client socket to my client computers network card. I also changed the way I do memset (I thought I understood it, but I might not)
for the complete solution:
Current Setup:
I have two Ubuntu machines connected together by a simple switch. The machines are what I am calling a server (ubuntu 16.04) and a client (ubuntu 14.04).
The first step I did is assign static IPs to each machine (I think this is only recommended for my server computer, but I didn't know how to get my DHCP address of my client in c).
in my server computer I opened my terminal (ctrl + alt + t)
sudo ifconfig enp6s0 192.168.1.1 netmask 255.255.255.0
in the client computer I opened my terminal and typed
sudo ifconfig eth0 192.168.1.2 netmask 255.255.255.0
now going back to the server computer in terminal I typed
gedit udp_server.c
which opened up a text editor
/************** UDP Server Code *****************/
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <ctype.h>
int main()
{
int udpSocket, nBytes;
char buffer[5];
struct sockaddr_in serverAddr, clientAddr;
struct sockaddr_storage serverStorage;
socklen_t addr_size, client_addr_size;
int i;
/* Create UDP socket */
udpSocket = socket(AF_INET, SOCK_DGRAM, 0);
/* Configure settings in address struct */
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(1024);
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
memset(serverAddr.sin_zero, '\0', sizeof(serverAddr.sin_zero);
/* Bind socket with address struct */
bind(udpSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr));
printf("bind complete port number %d\n", ntohs(serverAddr.sin_port));
/* Initialize size variable to be used later on */
addr_size = sizeof(serverStorage);
while(1)
{
nBytes = recvfrom(udpSocket, buffer, 5, (struct sockaddr *)&clientAddr, &addr_size);
printf("any bytes %d\n", nBytes);
}
return 0;
}
now for the client code I typed (on my client computer)
gedit udp_client.c
which opened up a text editor
/************ UDP client code **********/
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <stdlib.h>
int main()
{
int udpSocket, portNum, nBytes;
char buffer[1024] = "hello";
struct sockaddr_in serverAddr, clientAddr;
socklen_t addr_size;
unsigned int alen;
/* Create UDP socket */
udpSocket = socket(AF_INET, SOCK_DGRAM, 0);
/* Configure client settings in address struct */
memset((char *)&clientAddr, 0, sizeof(clientAddr));
clientAddr.sin_family = AF_INET;
clientAddr.sin_addr.s_addr = inet_addr("192.168.1.2");
clientAddr.sin_port = htons(0);
if(bind(udpSocket, (struct sockaddr *)&clientAddr, sizeof(clientAddr)) < 0)
{
perror("bind failed");
return 0;
}
printf("client bound");
/* configure server settings in struct */
memset((char *)&serverAddr, '0', sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(1024);
serverAddr.sin_addr.s_addr = inet_addr("192.168.1.1");
printf("the socket ip addr is: %s\n", inet_ntoa(clientAddr.sin_addr));
addr_size = sizeof(serverAddr);
while(1)
{
sleep(2);
nBytes = strlen(buffer);
if(sendto(udpSocket, buffer, nBytes, 0, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == -1)
{
perror("send to");
exit(1);
}
printf("sent %s\n", buffer);
}
return 0;
}
some extra notes
I actually don't know if I need to bind my sockets on my client side? I bound it to port 0 and everything worked peachey. I am thinking might run into issues if I try to receive from the server?
I am still working on a metaphor for how to think about ports
I am going with that the IP address is the network card address (city) and the port number is the address within that city (task, application). Like many people can reside in a city, many tasks or programs can reside on a machine and each one might want to communicate to the world.
This is only the most basic information (I don't cover other things like connect(), send(), write(), sendmsg() as I don't know how to use them)
hopefully this post makes it easier on the next guy.
I wrote a simple application which connects to a given server on a given port. When the port is open, everything is ok, I got the message about the established connection. However, when the port is closed, nothing happens, my program does not show me the information about it.
I test my program using my remote server accessible via the Internet. How can I improve this?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
int main(int argc, char **argv) {
char * ip_addr;
int port;
int sockfd;
struct sockaddr_in server_addr;
if (argc != 3)
{
fprintf(stderr,"Usage: ./canconnect ip port\n");
exit(1);
}
ip_addr = argv[1];
port = atoi(argv[2]);
if (port <= 0)
{
fprintf(stderr,"error: invalid port\n");
exit(1);
}
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket");
exit(1);
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
inet_aton(ip_addr, &server_addr.sin_addr);
if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1)
{
perror("connect");
printf("Port %d is closed on server %s.\n", port, ip_addr);
exit(1);
}
else
{
printf("Connection established. Port %d is open on server %s.\n", port, ip_addr);
}
close(sockfd);
return 0; }
Given that the program actually prints some data after some time, it's most certainly has to do with timeout.
In order to finally decide that the host or the port is unreadable or the connection couldn't be established for any other reason, connect performs several attempts to connect and returns an error after a certain amount of time - the timeout.
The value of timeout can be changed to any value you want using setsockopt:
struct timeval timeout;
timeout.tv_sec = 3; // wait for three seconds
timeout.tv_usec = 0;
// set up receive timeout
if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout,
sizeof(timeout)) < 0)
printf("[!] setsockopt failed\n");
If the remote server is reachable, but neither accepts nor refuses the connection, then connect() will block until the network connection attempt times out. As the Linux manual page for connect(2) puts it:
Note that for IP sockets the timeout may be very long when syncookies are enabled on the server.
Indeed, it is a well-known defense against port scans to attempt to elicit that behavior intentionally. You might be able to get quicker failures by using setsockopt() to set a receive timeout, but the docs are inconsistent on whether that will work for connect().
I know that this is obviously elementary question and I know that there are many tutorials and ready-to-go examples but I must missing something. I am trying to send for example text (char *) via UDP socket to other machine in local network. So far I tried some tutorials like http://gafferongames.com/networking-for-game-programmers/sending-and-receiving-packets/ and so on but I always get error in bind() function with errno "Cannot assign requested address".
I just have some data in char array and I want to push them via network to another host. Could someone please point me to the right direction? Do I need socket server or client? Do I need to bind the socket to some interface?
This is my playground:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <errno.h>
int handle;
int init_socket()
{
handle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (handle <= 0)
{
printf("failed to create socket\n");
return 1;
}
printf("sockets successfully initialized\n");
return 0;
}
int main ()
{
unsigned short port = 30000;
char * data = "hovno";
init_socket();
struct sockaddr_in address;
memset((char *) &address, 0, sizeof(address));
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr("192.168.11.129"); // this is address of host which I want to send the socket
address.sin_port = htons(port);
printf("handle: %d\n", handle); // prints number greater than 0 so I assume handle is initialized properly
if (bind(handle, (const struct sockaddr*) &address, sizeof(struct sockaddr_in)) < 0)
{
printf("failed to bind socket (%s)\n", strerror(errno)); // Cannot assign requested address
return 1;
}
int nonBlocking = 1;
if (fcntl(handle, F_SETFL, O_NONBLOCK, nonBlocking) == -1)
{
printf("failed to set non-blocking\n");
return 2;
}
int sent_bytes = sendto(handle, data, strlen(data), 0, (const struct sockaddr*) &address, sizeof(struct sockaddr_in));
if (sent_bytes != strlen(data))
{
printf("failed to send packet\n");
return 3;
}
return 0;
}
bind is called for the local address (one you intend to recv packets to). The IP address must be a local IP address of the machine, or (most frequently) INADDR_ANY.
Normally you don't have to use bind on the client side at all. The system will pick a suitable free port for you automatically.
To specify the remote address for a UDP socket, use sendto, not send.
If you search Google for udp client c code, one of the first results is this one. You can see that the networking part is basically just two calls, socket and sendto.
How can I make sure that my client uses a particular port to connect to server in a typical server client program. Like in server side we are using a port number in bind system call and then listen on that particular port, is there any way we can specify the port number on the client side and uses the same port to connect to server. Server = 3456 ,
Client = 7834 ( I want to specify this port number so that client uses 7834 for connection). I am trying in C and Unix platform.
You do this on the client side exactly as you do it on the server side - using bind(). It's just that the client calls connect() after bind() instead of calling listen().
Note that you will only be able to run one instance of the client on each machine if you do this, and your server might see a different client port anyway if there are network middleboxes using address translation between the client and server.
The client program can set sockaddr...sin_port and then call bind() before connecting and it will get, subject to availability, the requested outgoing port.
The server can verify this port is set manually by calling getpeername() and checking it.
As others have said though, you dont really need to set the outgoing port usually, unless you have something weird going on, or specific requirements.
It's similar with server side, usually we do
local_addr.sin_port = htons(INADDR_ANY);
because port number is not important. Instead, you can use
local_addr.sin_port = htons(src_port); /Use the src_port as you like
And then call bind
Here is a working solution that runs in debian linux on the ts-7500 sbc. it should port pretty easy. This solution also looks up the ip address of the client machine automatically.
/*dl_senderprog.c - debian linux send to server a client, datagram*/
/***********************************************************************
140203 lets see if we can bind to a port
ts7500:/var/www/jon/uvir_sensor_lab/source/socket#
ts7500:/var/www/jon/uvir_sensor_lab/source/socket# vi senderprog_bind.c
ts7500:/var/www/jon/uvir_sensor_lab/source/socket# gcc -g senderprog_bind.c -o senderprog_bind
ts7500:/var/www/jon/uvir_sensor_lab/source/socket# ./senderprog_bind
Sender:Client-Usage: ./senderprog_bind <hostname> <message>
ts7500:/var/www/jon/uvir_sensor_lab/source/socket#
ts7500:/var/www/jon/uvir_sensor_lab/source/socket#
ts7500:/var/www/jon/uvir_sensor_lab/source/socket# ./senderprog_bind 10.0.1.26 "dot,33,22"
MY IP address:10.0.1.242: on port: 1043
Sender: Client-gethostname() is OK...
Sender: Client-socket() sockfd is OK...
Sender: Using port: 14950
Sender: Client-sendto() is OK...
Sender: sent 9 bytes to 10.0.1.26
Sender: Client-sockfd successfully closed!
ts7500:/var/www/jon/uvir_sensor_lab/source/socket#
ts7500:/var/www/jon/uvir_sensor_lab/source/socket#
ts7500:/var/www/jon/uvir_sensor_lab/source/socket# # it worked!!!!!
ts7500:/var/www/jon/uvir_sensor_lab/source/socket#
***********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/ioctl.h>
#include <net/if.h>
/* the port users will be connecting to 14950 is the port on the windows machine
that I have the server running on */
#define TOPORT 14950
#define MYPORT 1043
void my_ip( char *myniccard, char *myipaddr) {
int fd;
struct ifreq ifr;
myipaddr[0]=0;
fd = socket(AF_INET, SOCK_DGRAM, 0);
/* I want to get an IPv4 IP address */
ifr.ifr_addr.sa_family = AF_INET;
/* I want IP address attached to "eth0" */
//strncpy(ifr.ifr_name, "eth0", IFNAMSIZ-1);
strncpy(ifr.ifr_name, myniccard, IFNAMSIZ-1);
ioctl(fd, SIOCGIFADDR, &ifr);
close(fd);
/* display result */
sprintf(myipaddr,"%s"
, inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr));
printf("MY IP address:%s: on port: %d\n", myipaddr, MYPORT);
} // my_ip
int main(int argc, char *argv[ ])
{
int sockfd;
/* connectors address information */
struct sockaddr_in their_addr;
struct sockaddr_in localaddr;
char myipaddressm[22]; //buffer for ip address
char *myniccardm ="eth0"; // check with ipconfig for correct ethernet port
struct hostent *he;
int numbytes;
if (argc != 3) {
fprintf(stderr, "Sender:Client-Usage: %s <hostname> <message>\n", argv[0]);
exit(1);
}
my_ip(myniccardm, myipaddressm);
/* get the host info */
if ((he = gethostbyname(argv[1])) == NULL) {
perror("Sender: Client-gethostbyname() error lol!");
exit(1);
}
else
printf("Sender: Client-gethostname() is OK...\n");
if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
perror("Sender: Client-socket() error lol!");
exit(1);
}
else
printf("Sender: Client-socket() sockfd is OK...\n");
// Bind to a specific network interface
// (this is unusual, as you normally do not want a specific
// port for the client, but we have a specific server in
// this case that will not accept connects unless its on
// a specific port )
localaddr.sin_family = AF_INET;
localaddr.sin_addr.s_addr = inet_addr(myipaddressm);
localaddr.sin_port = htons(MYPORT); // Any local port will do
bind(sockfd, (struct sockaddr *)&localaddr, sizeof(localaddr));
/* host byte order */
their_addr.sin_family = AF_INET;
/* short, network byte order */
printf("Sender: Using port: %d\n",TOPORT);
their_addr.sin_port = htons(TOPORT);
their_addr.sin_addr = *((struct in_addr *)he->h_addr);
/* zero the rest of the struct */
memset(&(their_addr.sin_zero), '\0', 8);
if((numbytes = sendto(sockfd, argv[2],
strlen(argv[2]),
0,
(struct sockaddr *)&their_addr,
sizeof(struct sockaddr))) == -1) {
perror("Sender: Client-sendto() error lol!");
exit(1);
}
else
printf("Sender: Client-sendto() is OK...\n");
printf("Sender: sent %d bytes to %s\n", numbytes, inet_ntoa(their_addr.sin_addr));
if (close(sockfd) != 0)
printf("Sender: Client-sockfd closing is failed!\n");
else
printf("Sender: Client-sockfd successfully closed!\n");
return 0;
}//main
/*******************************************EOF***********************/