binding server socket to port fails (C) - c

My code will always proc the "Binding Failure" error and I do not know why. I have read the man page multiple times and I can't find anything wrong with the code, can someone please steer me in the right direction?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT 3490
#define BACKLOG 10
int main()
{
struct sockaddr_in server;
struct sockaddr_in dest;
int status,socket_fd, client_fd,num;
socklen_t size;
char buffer[10241];
char *buff;
// memset(buffer,0,sizeof(buffer));
int yes =1;
if ((socket_fd = socket(AF_INET, SOCK_STREAM, 0))== -1) {
fprintf(stderr, "Socket failure!!\n");
exit(1);
}
if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
perror("setsockopt");
exit(1);
}
memset(&server, 0, sizeof(server));
memset(&dest,0,sizeof(dest));
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
server.sin_addr.s_addr = INADDR_ANY;
if ((bind(socket_fd, (struct sockaddr *)&server, sizeof(struct sockaddr )))== -1) { //sizeof(struct sockaddr)
fprintf(stderr, "Binding Failure\n");
exit(1);
//other irrelevant code starts here

If netstat -an|grep 3490 really shows 127.0.0.1 you have another process listening at the port, bound to 127.0.0.1 instead of INADDR_ANY, which is why the SO_REUSEADDR didn't work. But you will never know for sure until you take my advice above.

After using perror, I found that the address was taken and I switched to another port and it worked!

Related

can't retrieve error through getsockopt while errno = 13

The following code opens a UDP socket and binds to a privileged port which fails. I want to retrieve the error through getsockopt (SO_ERROR) but I can't. The errno var is 13 but from getsockopt I get 0. I was under the impression getsockopt was the preferred method?
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <sys/time.h>
#include <errno.h>
int main() {
int _fd = socket (AF_INET, SOCK_DGRAM,
IPPROTO_UDP);
int on = 1;
int rc = setsockopt (_fd, SOL_SOCKET, SO_REUSEADDR,
reinterpret_cast<char *> (&on), sizeof (on));
assert(rc == 0);
struct sockaddr_in server;
memset(&server, 0, sizeof server);
server.sin_family = AF_INET; // Use IPv4
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons(151); // Bind port
rc = rc | bind (_fd, (struct sockaddr *)&server, sizeof(server));
int err = -1;
socklen_t len = sizeof err;
int rc2 = getsockopt (_fd, SOL_SOCKET, SO_ERROR, &err, &len);
printf("end rc=%i rc2=%i err=%i errno=%i : %m\n", rc, rc2, err, errno);
sleep(10);
}
I think you misunderstand what SO_ERROR is for. It's not a substitute for errno - that has already told you why the call to bind failed.
Instead, it is meant to be used for established connections that might encounter an error condition which cannot be reported immediately (such as an asychronous operation on a non-blocking socket). There's a better description than the rather bare-bones man page here:
https://www.ibm.com/docs/en/zvse/6.2?topic=SSB27H_6.2.0/fa2ti_call_getsockopt.htm

Why isn't this c client able to read data sent by this c server if the latter calls the write system call twice?

How come this client is only able to read data sent from the first server write system call ? It correctly reads the data sent by the first write, but not with the second one...
Here's the client :
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define PORT 1025
#define SA struct sockaddr
int main(){
int sockfd;
struct sockaddr_in servaddr, cli;
//CREATE SOCKET
sockfd = socket(AF_INET, SOCK_STREAM,IPPROTO_TCP);
if (sockfd == -1) {
printf("socket creation failed...\n");
exit(0);
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
servaddr.sin_port = htons(PORT);
if (connect(sockfd, (SA*)&servaddr, sizeof(servaddr)) != 0) {
printf("connection with the server failed...\n");
exit(0);
}
char buff[1024];
while( (read(sockfd, buff,sizeof(buff))) > 0){
printf("%s\n",buff);
}
close(sockfd);
return 0;
}
And here is the server :
#include <stdio.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#define SA struct sockaddr
#define PORT 1025
int main(){
int sockfd, connfd;
unsigned int len;
struct sockaddr_in servaddr, cli;
//SOCKET CREATION
sockfd = socket(AF_INET, SOCK_STREAM,IPPROTO_TCP);
if (sockfd == -1) {
printf("socket creation failed...\n");
exit(0);
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr =htonl(INADDR_ANY);
servaddr.sin_port = htons(PORT);
//BIND
if ((bind(sockfd, (SA*)&servaddr, sizeof(servaddr))) != 0) {
printf("socket bind failed...\n");
exit(0);
}
//LISTEN
if ((listen(sockfd, 5)) != 0) {
printf("Listen failed...\n");
exit(0);
}
for(;;){
len = sizeof(cli);
connfd = accept(sockfd, (SA*)&cli, &len);
if (connfd < 0) {
printf("server accept failed...\n");
exit(0);
}
char buff[]="Hi";
char buff2[]="More data sent..\n";
write(connfd,buff,sizeof(buff)); //work
write(connfd,buff2,sizeof(buff2)); //doesn't work
close(connfd);
}
return 0;
}
I also noticed it works if I put the second write inside a loop that requires a certain amount of time. For example :
long max=0;
while(max<1000000000){
//second write works
write(......);
}
Could someone give an explanation of why write behaves like that and what's going on under the hood ?

Get IP addresses of all devices connected (UDP)

I have looked for a similar question, but I could not find one that would work for me. I am doing a simple project for one of my subjects, but I never had experience with sockets, so I need some help with the implementation of one feature.
Basically, there are several units interconnected by a communication network (physical ETHERNET 1Gbps, TCP / IP protocol), and I have to be able to communicate with all the boards. I can implement all other features I need on one specific board, but I don't know how to manipulate all the boards simultaneously.
So, the question is: how to get a list of all boards connected and how to select which board should receive/send a message?
Big thanks to anyone who would help.
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <time.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <string.h>
#include "mzapo_parlcd.h"
#include "mzapo_phys.h"
#include "mzapo_regs.h"
#define MY_PORT 55555
#define BUFLEN 512
int main(int argc, char *argv[])
{
int sockfd;
char buffer[BUFLEN];
struct sockaddr_in peeraddr;
// SET UP A NETWORK SOCKET
if ((sockfd = socket (AF_INET, SOCK_DGRAM, 0)) == -1) {
perror("socket");
exit(1);
}
int broadcast = 1;
if (setsockopt (sockfd, SOL_SOCKET, SO_BROADCAST, & broadcast,
sizeof broadcast) == -1) {
perror("setsockopt (SO_BROADCAST)");
exit(1);
}
struct sockaddr_in bindaddr;
memset(&bindaddr, 0, sizeof(bindaddr));
bindaddr.sin_family = AF_INET;
bindaddr.sin_port = htons(MY_PORT);
bindaddr.sin_addr.s_addr = INADDR_ANY;
int yes=1;
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes,
sizeof(yes)) == -1) {
perror("setsockopt (SO_REUSEADDR)");
exit(1);
}
if (bind(sockfd, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) == -1) {
perror("bind");
exit(1);
}
broadcast = 1;
if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &broadcast,
sizeof broadcast) == -1) {
perror("setsockopt (SO_BROADCAST)");
exit(1);
}
struct sockaddr_in braddr;
memset(&braddr, 0, sizeof(braddr));
braddr.sin_family = AF_INET;
braddr.sin_port = htons(MY_PORT );
braddr.sin_addr.s_addr = INADDR_BROADCAST;
strncpy(buffer, "Hello world", sizeof(buffer));
char* ipString = inet_ntoa(bindaddr.sin_addr);
while(1){
printf("%s", ipString);
if (sendto(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr *)&braddr, sizeof(braddr)) == -1){
perror("sendto");
exit(1);
}
peeraddr_len = sizeof(peeraddr);
}
return 0;
}

View TCP header fields from C program running on Debian

I've successfully made an "echo client", and I'd like to add robustness before moving along to the rest of my project. Notably I'd like to view the "TCP window size" value inside the TCP header, and ensure that I don't flood the server with my next transmission.
I am not sure if this is possible without using raw sockets and forming/parsing the TCP header myself. While that isn't impossible, I'd prefer to use built in functions to access the header with my current code if possible. Please let me know if you have any suggestions.
#include "../include/a8gcc.hpp"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <errno.h>
#define buffer_len 512
/* server address */
#define SERVER "192.168.2.115"
/* server port number */
#define SERVPORT 10001
int main(void)
{
struct sockaddr_in serv_addr;
struct hostent *server;
int sock_fd, num_read = 0;
char in_data[buffer_len];
printf("is_ethernet from GCC");
setbuf(stdout, NULL);
sock_fd = socket(AF_INET, SOCK_STREAM, 0);
if(sock_fd < 0){
perror("Opening socket error");
exit(1);
}else{
printf("Opening the socket...OK.\n");
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
server = gethostbyname(SERVER);
if(server == NULL){
printf("%s \n", h_errno);
perror("getting host address error");
exit(1);
}
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(SERVPORT);
if (connect(sock_fd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0){
perror("ERROR connecting");
exit(1);
}
while(1){
num_read = read(sock_fd,in_data,buffer_len);
write(sock_fd,in_data,num_read);
}
return 0;
}
I do not believe that it is possible for you to examine the actual content of the TCP/IP headers from within your code unless you are going to use raw sockets and generate the packets yourself. :( Sorry!

communication between windows client and linux server?

I am performing communication between client(windows) and server(linux RT) in c. I have written a client code for windows operating system (one laptop) and server code for linux operating system (another laptop). I am connecting the both laptop via ethernet cable and configured them on the same subnet.
SERVER.c : Linux
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#define BUFLEN 512
#define PORT 9930
void err(char *str)
{
perror(str);
exit(1);
}
int main(void)
{
struct sockaddr_in my_addr, cli_addr;
int sockfd, i;
socklen_t slen=sizeof(cli_addr);
char buf[BUFLEN];
if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
err("socket");
else
printf("Server : Socket() successful\n");
bzero(&my_addr, sizeof(my_addr));
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(PORT);
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(sockfd, (struct sockaddr* ) &my_addr, sizeof(my_addr))==-1)
err("bind");
else
printf("Server : bind() successful\n");
while(1)
{
if (recvfrom(sockfd, buf, BUFLEN, 0, (struct sockaddr*)&cli_addr,
&slen)==-1)
err("recvfrom()");
printf("Received packet from %s:%d\nData: %s\n\n",
inet_ntoa(cli_addr.sin_addr), ntohs(cli_addr.sin_port), buf);
}
close(sockfd);
return 0;
}
CLIENT.c - windows
#pragma comment(lib, "Ws2_32.lib")
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <time.h>
#include <winsock.h>
#include <io.h>
#define BUFLEN 512
#define PORT 9930
void err(char *str)
{
perror(str);
exit(1);
}
int main(void)
{
struct sockaddr_in my_addr, cli_addr;
int sockfd, i;
socklen_t slen=sizeof(cli_addr);
char buf[BUFLEN];
WORD wVersionRequested;
WSADATA wsaData;
printf("Initializing Winsock\n");
wVersionRequested = MAKEWORD (1, 1);
if (WSAStartup (wVersionRequested, &wsaData) != 0){
printf("Winsock initialised failed \n");
} else {
printf("Initialised\n");
if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
err("socket");
bzero(&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
if (inet_aton(argv[1], &serv_addr.sin_addr)==0)
{
fprintf(stderr, "inet_aton() failed\n");
exit(1);
}
while(1)
{
printf("\nEnter data to send(Type exit and press enter to exit) : ");
scanf("%[^\n]",buf);
getchar();
if(strcmp(buf,"exit") == 0)
exit(0);
if (sendto(sockfd, buf, BUFLEN, 0, (struct sockaddr*)&serv_addr, slen)==-1)
err("sendto()");
}
close(sockfd);
return 0;
}
My question :
Is it possible to perform communication like this ??
Do I want to take specific measures for doing this ??
Please give ideas regarding this ?
You can connect two systems directly (via ethernet cable), but typically you must use a special cable for that: it is called a "crossover cable". Otherwise no connection is possible.
Newer network controllers implement a detection for this kind of setup, so it might be possible to use a standard cable for this setup, but this depends on the network controllers build into the two systems. You will have to try or consult the documentation.
Also it migh be that you have to select some special configuration on the MS-Windows side (inside the network adapter configuration) for this to work. I experienced communication problems with the standard setup a few times. You can consult google for those settings.

Resources