C socket programming no port entered - c

I'm trying to set a default port number for when no port is entered in C socket programming. Does anyone know how I can do this? I keep getting segmentation fault on attempts.
Code:
#define PORT 12345
int main(int argc, char *argv[]) {
/* Thread and thread attributes */
pthread_t client_thread;
pthread_attr_t attr;
int sockfd, new_fd; /* listen on sock_fd, new connection on new_fd */
struct sockaddr_in my_addr; /* my address information */
struct sockaddr_in their_addr; /* connector's address information */
socklen_t sin_size;
int i=0;
/* Get port number for server to listen on */
if (argc != 2) {
fprintf(stderr,"usage: client port_number\n");
exit(1);
}
/* generate the socket */
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
/* generate the end point */
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(atoi(argv[1]));
my_addr.sin_addr.s_addr = INADDR_ANY;
I tried setting the default to 12345 when argc != 2, but I get segmentation fault. Any help would be appreciated!

You can use a conditional expression.
#define DEFAULT_PORT 12345
my_addr.sin_port = htons(argc < 2 ? DEFAULT_PORT : atoi(argv[1]));

Related

UDP Socket Programming - recvfrom() one Port and sendto() other Port

UDP Socket Programming - Server listening on Port 5000 - Client listening on Port 6000
recvfrom() from one Port - 5000
sendto() to other Port - 6000 to the same client.
Server.c
#include <stdio.h> /* for printf() and fprintf() */
#include <sys/socket.h> /* for socket() and bind() */
#include <arpa/inet.h> /* for sockaddr_in and inet_ntoa() */
#include <stdlib.h> /* for atoi() */
#include <string.h> /* for memset() */
#include <unistd.h> /* for close() */
#define MAXSIZE 255 /* Longest string */
#define SRC_PORT 5000
#define DST_PORT 6000
int main(int argc, char *argv[])
{
int sock; /* Socket */
struct sockaddr_in ServAddr; /* Local address */
struct sockaddr_in ClntAddr; /* Client address */
socklen_t CliAddrLen; /* Length of incoming message */
char recBuffer[MAXSIZE]; /* Buffer for echo string */
int recvMsgSize; /* Size of received message */
int i;
/* Create socket for sending/receiving datagrams */
if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
DieWithError("socket() failed");
/* Construct local address structure */
memset(&ServAddr, 0, sizeof(ServAddr)); /* Zero out structure */
ServAddr.sin_family = AF_INET; /* Internet address family */
ServAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */
ServAddr.sin_port = htons(SRC_PORT); /* Local port */
/* Construct address structure */
memset(&ClntAddr, 0, sizeof(ClntAddr)); /* Zero out structure */
ClntAddr.sin_family = AF_INET; /* Internet address family */
ClntAddr.sin_addr.s_addr = inet_addr("192.168.1.*");
ClntAddr.sin_port = htons(DST_PORT);
/* Bind to the local address */
if (bind(sock, (struct sockaddr *) &ServAddr, sizeof(ServAddr)) < 0)
DieWithError("bind() failed");
for (;;) /* Run forever */
{
printf("Listening on UDP:5000 \n");
/* Set the size of the in-out parameter */
cliAddrLen = sizeof(ClntAddr);
/* Block until receive message from a client */
if ((recvMsgSize = recvfrom(sock, recBuffer, MAXSIZE, 0,(struct sockaddr *) &ClntAddr, &cliAddrLen)) < 0)
DieWithError("recvfrom() failed") ;
printf("Handling Client: %s\n", inet_ntoa(ClntAddr.sin_addr));
printf("Received Data: %s",recBuffer);
printf("\n");
/* Send response datagram back to the client */
if (sendto(sock, recBuffer, MAXSIZE, 0, (struct sockaddr *) & ClntAddr, sizeof(ClntAddr)) < 0)
DieWithError("sendto() failed");
}
/* NOT REACHED */
}
It works perfectly. Client and Server programming using different ports for sending and receiving the data.
Thank you
Regards
this is wrong
lntAddr.sin_addr.s_addr = inet_addr("CLIENT_IP");
inet_addr takes a dotted ip address not a host name

How to receive and send in different threads with C sockets

I am trying to send and receive in different threads. When I use the code below I get a bad address error, I guess because my server address could not be properly passed to the thread function.
Code:
#include "client.h"
struct global_table{
struct sockaddr_in *serveraddr;
int sockID;
};
void *recvFromServer(struct global_table *rec){
char recBuf[RECVBUFSIZE];
int serverSize = sizeof(rec->serveraddr);
while(1)
{
int n = recvfrom(rec->sockID, recBuf, RECVBUFSIZE, 0, &rec->serveraddr, &serverSize);
if (n < 0)
perror("ERROR in recvfrom");
decryptData(recBuf);
printf("Recieved: %s\n", recBuf);
pthread_exit(NULL);
}
}
void pingServer(char *hostname, int portno)
{
int sockfd, n, serverlen;
struct sockaddr_in serveraddr;
struct sockaddr_in client_addr;
struct hostent *server;
char *buf;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0)
perror("ERROR opening socket");
server = gethostbyname(hostname);
if (server == NULL)
perror("ERROR, no host found");
bzero((char *) &serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
bcopy((char *)server->h_addr, (char *)&serveraddr.sin_addr.s_addr, server->h_length);
serveraddr.sin_port = htons(portno);
client_addr.sin_family = AF_INET;
client_addr.sin_addr.s_addr = htonl(INADDR_ANY);
client_addr.sin_port = htons(5500);
if (bind(sockfd,(struct sockaddr *)&client_addr, sizeof(struct sockaddr)) == -1)
perror("Socket could not be binded");
if(setsockopt(sockfd,IPPROTO_IP,IP_TOS,&tos,sizeof(tos)))
perror("Could not set socket option");
pthread_t threads[2];
serverlen = sizeof(serveraddr);
struct global_table server_info;
server_info.sockID = sockfd;
server_info.serveraddr = &serveraddr;
pthread_create(&threads[0],NULL,recvFromServer, &server_info); // Trying to recv on a different thread
pthread_join(threads[0],NULL);
}
int main(int argc, char **argv) {
char *hostname;
int portno;
if (argc != 3)
perror("usage: <hostname> <port>\n");
hostname = argv[1];
portno = atoi(argv[2]);
pingServer(hostname, portno);
return 0;
}
How can I fix the problem?
In addition to the problems noted in the comments (and by now, this problem is also noted in the comments...), this line
struct global_table server_info;
creates a local variable in your pingServer() function.
This line
pthread_create(&threads[0],NULL,recvFromServer, &server_info); // Trying to recv on a different thread
of code passes the address of that variable to the recvFromServer() function, which will run in a different thread. But then pingServer() immediately returns and the local server_info variable ceases to exist.
One fix is to define the server_info and serveraddr variable as static:
static struct global_table server_info;
static struct sockaddr_in serveraddr;
That will create one copy of the server_info variable that will be shared by every invocation of pingServer(), but that one copy will exist for the lifetime of your program.

accept() keeps returning 0

This is a simple server that merely accepts connections, then prints the socket descriptor. For some reason, whenever I run this the only socket descriptors I receive are of value 0. This even occurs with multiple clients connecting simultaneously. I seem to be misunderstanding something to do with the behavior of accept(), or there is some bug I cannot locate in my code. Here is the code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
/* Utility for consisely killing the program. */
void abort_program(const char *error_message)
{
fputs(error_message, stderr);
exit(EXIT_FAILURE);
}
/* Establishes a passive listening port, returns socket descriptor. */
int setup_passive_port(int port)
{
struct protoent *ptrp; // pointer to a protocol table entry
struct sockaddr_in sad; // structure to hold server's address
int sd; // socket descriptor for listening
/* Map TCP transport protocol name to protocol number. */
if (((long int) (ptrp = getprotobyname("tcp"))) == 0)
abort_program("ERROR: Cannot map TCP to protocol number\n");
/* Create a socket. */
sd = socket(PF_INET, SOCK_STREAM, ptrp->p_proto);
if (sd < 0)
abort_program("ERROR: Socket creation failed\n");
/* Prepare the socket address structure. */
memset((char *) &sad, 0, sizeof(sad));
sad.sin_family = AF_INET;
sad.sin_addr.s_addr = INADDR_ANY;
sad.sin_port = htons((u_short) port);
/* Bind a local address to the socket. */
if (bind(sd, (struct sockaddr*) &sad, sizeof(sad)) < 0)
abort_program("ERROR: Bind failed\n");
/* Establish passive listener socket. */
if (listen(sd, 0) < 0)
abort_program("ERROR: Listen failed\n");
return sd;
}
int main(int argc, char *argv[])
{
struct sockaddr_in cad; // structure to hold client's address
int alen; // length of address
int sd; // incoming socket
int listener; // listening socket
listener = setup_passive_port(30000);
while (1) {
if (sd = accept(listener, (struct sockaddr*) &cad, &alen) < 0)
abort_program("ERROR: Accept failed\n");
printf("%d\n", sd);
}
}
Can you help me understand why? Thanks for your consideration.
One thing you need to do is to set your alen to the sizeof(sockaddr_in) prior to calling accept(). The other is that at least clang complains about the missing brackets within your if( accept()...) line. Here the fixed up version.
telnet localhost 30000 worked as expected.
Also changed your int alen to socklen_t alen while being at it.
int main(int argc, char *argv[])
{
struct sockaddr_in cad; // structure to hold client's address
socklen_t alen = sizeof(sockaddr_in); // length of address
int sd; // incoming socket
int listener; // listening socket
listener = setup_passive_port(30000);
while (1) {
if ((sd = accept(listener, (struct sockaddr*) &cad, &alen)) < 0)
abort_program("ERROR: Accept failed\n");
printf("%d\n", sd);
}
}

Why doesn't accept() block?

I'm new in socket programming under Linux (UNIX) sockets.
I found the following code in the Internet, for a tcp-server that spawns a thread for each connection.
However it doesn't work.
the accept() function returns instantly, and doesn't wait for connection.
What am I doing wrong ?
this is the code
int main(int argv, char *args[])
{
struct sockaddr_in addr;
int sd, port;
port = htons(SERVER_PORT);
/*--- create socket ---*/
sd = socket(PF_INET, SOCK_STREAM, 0);
if ( sd < 0 )
panic("socket");
/*--- bind port/address to socket ---*/
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = port;
addr.sin_addr.s_addr = INADDR_ANY; /* any interface */
if ( bind(sd, (struct sockaddr*)&addr, sizeof(addr)) != 0 )
panic("bind");
/*--- make into listener with 10 slots ---*/
if ( listen(sd, 10) != 0 )
panic("listen")
/*--- begin waiting for connections ---*/
else
{ int sd;
pthread_t child;
FILE *fp;
while (1) /* process all incoming clients */
{
sd = accept(sd, 0, 0); /* accept connection */
fp = fdopen(sd, "wr+"); /* convert into FILE* */
pthread_create(&child, 0, servlet, fp); /* start thread */
pthread_detach(child); /* don't track it */
}
}
}
You are shadowing the sd variable, passing an invalid socket to accept() which causes it to fail immediately.
It will likely return EBADF to signal a bad file descriptor. You would have noticed if you checked the return value in your code.
You should enable more compiler warnings, to catch things like these. With GCC you can use the -Wshadow option to enable such a warning.
You're not checking the return value of accept() call. Most likely it's returning an error.
there's a redefinition of sd variable
int sd;
Some problems:
1) You are missing a comma on panic("listen")
2) You are declaring "sd" twice (one at main() one at else)
#include <stdio.h>
#include <pthread.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#define SERVER_PORT 30000
int main(int argv, char *args[])
{
struct sockaddr_in addr;
int sd, port;
port = htons(SERVER_PORT);
/*--- create socket ---*/
sd = socket(PF_INET, SOCK_STREAM, 0);
/*--- bind port/address to socket ---*/
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = port;
addr.sin_addr.s_addr = INADDR_ANY; /* any interface */
bind(sd, (struct sockaddr*)&addr, sizeof(addr));
/*--- make into listener with 10 slots ---*/
listen(sd, 10);
/*--- begin waiting for connections ---*/
pthread_t child;
FILE *fp;
while (1) /* process all incoming clients */
{
printf("before accept\n");
sd = accept(sd, 0, 0); /* accept connection */
fp = fdopen(sd, "wr+"); /* convert into FILE* */
//pthread_create(&child, 0, servlet, fp); /* start thread */
//pthread_detach(child); /* don't track it */
printf("After accept\n");
}
}
their is a redefinition of variable sd.
int sd; // at line 3 and 26

Broadcasting a message to multiple clients from a server using UDP protocol

i have two code here for a UDP chat with a broadcasting mechanism where the server can broadcast a message to all clients simultaneously
Server code...
#include<stdio.h>
#include<string.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
int main(int argc, char *argv[] )
{
struct sockaddr_in client,server;
int s,n;
char b1[100],b2[100];
s=socket(AF_INET,SOCK_DGRAM,0);
server.sin_family=AF_INET;
server.sin_port=htons(2000);
server.sin_addr.s_addr=inet_addr("127.0.0.1");
bind(s,(struct sockaddr *)&server,sizeof(server));
printf("\nServer ready,waiting for client....\n");
n=sizeof(client);
int sock; /* Socket */
struct sockaddr_in broadcastAddr; /* Broadcast address */
char *broadcastIP; /* IP broadcast address */
unsigned short broadcastPort; /* Server port */
char *sendString; /* String to broadcast */
int broadcastPermission; /* Socket opt to set permission to broadcast */
unsigned int sendStringLen; /* Length of string to broadcast */
if (argc < 4) /* Test for correct number of parameters */
{
fprintf(stderr,"Usage: %s <IP Address> <Port> <Send String>\n", argv[0]);
exit(1);
}
broadcastIP = argv[1]; /* First arg: broadcast IP address */
broadcastPort = atoi(argv[2]); /* Second arg: broadcast port */
sendString = argv[3]; /* Third arg: string to broadcast */
/* Create socket for sending/receiving datagrams */
sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
broadcastPermission = 1;
while(1)
{
recvfrom(s,b1,sizeof(b1),0,(struct sockaddr *) &client,&n);
if(!(strcmp(b1,"end")))
break;
printf("\nClient:%s",b1);
printf("\nServer:");
gets(b2);
sendto(s,b2,sizeof(b2),0,(struct sockaddr *) &client,n);
broadcastPermission = 1;
setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (void *) &broadcastPermission,sizeof(broadcastPermission));
/* Construct local address structure */
//memset(&broadcastAddr, 0, sizeof(broadcastAddr)); /* Zero out structure */
broadcastAddr.sin_family = AF_INET; /* Internet address family */
broadcastAddr.sin_addr.s_addr = inet_addr(broadcastIP);/* Broadcast IP address */
broadcastAddr.sin_port = htons(broadcastPort); /* Broadcast port */
sendStringLen = strlen(sendString);
for (;;) /* Run forever */
{
/* Broadcast sendString in datagram to clients every 3 seconds*/
sendto(sock, sendString, sendStringLen, 0, (struct sockaddr *) &broadcastAddr, sizeof(broadcastAddr));
// DieWithError("sendto() sent a different number of bytes than expected");
//sleep(3); /* Avoids flooding the network */
}
}
}
Client code...
#include<stdio.h>
#include<string.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#define MAXRECVSTRING 255
int main(int argc , char argv[])
{
struct sockaddr_in client,server;
int s,n;
char b1[100],b2[100];
s=socket(AF_INET,SOCK_DGRAM,0);
server.sin_family=AF_INET;
server.sin_port=htons(2000);
server.sin_addr.s_addr=inet_addr("127.0.0.1");
printf("\nClient ready....\n");
n=sizeof(server);
int sock; /* Socket */
struct sockaddr_in broadcastAddr; /* Broadcast Address */
unsigned short broadcastPort; /* Port */
char recvString[MAXRECVSTRING+1]; /* Buffer for received string */
int recvStringLen; /* Length of received string */
if (argc != 2) /* Test for correct number of arguments */
{
fprintf(stderr,"Usage: %s <Broadcast Port>\n", argv[0]);
exit(1);
}
printf("\nClient ready…11111.\n");
broadcastPort = htons(argv[1]); /* First arg: broadcast port */
printf("\nClient ready….1\n");
/* Create a best-effort datagram socket using UDP */
if(sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)<0)
printf("no sock created");
printf("\nClient ready….2\n");
while(1)
{
printf("\nClient:");
gets(b2);
sendto(s,b2,sizeof(b2),0,(struct sockaddr *) &server,n);
if(strcmp(b2,"end")==0)
break;
recvfrom(s,b1,sizeof(b1),0,NULL,NULL);
printf("\nServer:%s",b1);
broadcastAddr.sin_family = AF_INET; /* Internet address family */
broadcastAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */
broadcastAddr.sin_port = htons(broadcastPort); /* Broadcast port */
/* Bind to the broadcast port */
bind(sock, (struct sockaddr *) &broadcastAddr, sizeof(broadcastAddr));
/* Receive a single datagram from the server */
recvStringLen = recvfrom(sock, recvString, MAXRECVSTRING, 0, NULL, 0);
recvString[recvStringLen] = '\0';
printf("Received: %s\n", recvString); /* Print the received string */
}
close(sock);
}
These code run without any error but when i send a string from client to the server the server is unable to receive the string and vice versa.
If someone could help me out as to why this is happening.
i am running both the server and client on the same system in different terminal windows..hence the local host address
Some platforms, e.g. Windows, won't receive broadcasts unless the socket is bound to INADDR_ANY, i.e. 0.0.0.0.
To start with:
server.sin_port=2000;
You forget to make this network-order.
In your server code:
The socket is not bound to any IP address. Although it broadcasts the message and the client receives; the vice-versa won't work.
Thus, bind your server and client side sockets to 2 different IP addresses.
When the server broadcasts the message, use appropriate broadcast address (see the subnet of the server-client IP) in the sendto function.

Resources