My router.c file creates 2 sockets
the first is to bind to a port and answer clients
the second is to connect to an already bound port (by the server.c file)
and send messages to.
for some reason the sendto line return an Invalid argument error.
please help.
#include <sys/types.h>
#include <netinet/in.h>
#include <inttypes.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <strings.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>
/* The Rounter represents through the server file(recv_udp.c).It transmitting from/to A(client) and C(another client)
by specific criteria (given in the assignment). */
int main(int argc, char *argv[])
{
/* Adding values that`ll be used for Q5*/
char serMsg [] = "Nice to hear from you,I am the server\n";
// char serMsg [] = "Good morning sun shine\n";
int serMsgLeng = strlen(serMsg)+1;
int error = -1;
char buff_A[200] = {'\0'};
char buff_C[200] = {'\0'};
// A value we get from the command prompt
float x;
float random, rand_num;
struct timeval tv;
tv.tv_sec = 3; /* 3 Seconds Time-out */
tv.tv_usec = 0;
/* Values that`ll receive for the socket I`ll open (as socket descriptor(an int) etc.) */
int socket_fd1,socket_fd2, cc, addrLenA, s_in2Size;
/* Randome number Raffled between the range of[0,1] */
double randNum;
/* Defining Structures for decleration of the server s_in= as serverAddr(local ip,and local port),
from_A = the address that the datagram was received from client A,
from_C-the address that the datagram was received from client C . */
struct sockaddr_in s_in1, s_in2;
// Defining Structures for handling the clients address(client A and client C)
// Client A address structure
struct sockaddr_in client_A_addr;
//Client C address structure
struct sockaddr_in client_C_addr;
x = atof(argv[1]);
// Creating UDPsocket-(it`s a system call)-the socket()function opens a local socket and saves it`s number in socket_fd value. */
socket_fd1 = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
socket_fd2 = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
/*set the socket options*/
setsockopt(socket_fd1, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval));
setsockopt(socket_fd2, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval));
// Binary cleaning /
bzero((char *) &s_in1, sizeof(s_in1)); /* They say you must do this */
bzero((char *) &s_in2, sizeof(s_in2));
/* Configure settings in address struct
"s_in.sin_family"-set the address family to be "AF_INET
"s_in.sin_addr.s_addr"- the htonl function converts host's to network's long
"s_in.sin_port" -the htons function converts regular form port to binary form.*/
s_in1.sin_family = (short)AF_INET;//host byte order
s_in1.sin_addr.s_addr = htonl(INADDR_ANY); // WILDCARD //
s_in1.sin_port = htons(1337);
s_in2.sin_family = (short)AF_INET;//host byte order
s_in2.sin_addr.s_addr = inet_addr("172.17.0.15"); // WILDCARD //
s_in2.sin_port = htons(1338);
// printsin( &s_in, "RECV_UDP", "Local socket is:");
fflush(stdout);
/* The bind function assigns a local protocol address to a socket(and another system call).
The purpose of sin here is to tell bind which local address to assign.
bind method input:the sock_fd and the stuctur that handels the address and it`s length*/
bind(socket_fd1, (struct sockaddr *)&s_in1, sizeof(s_in1));
printf("After binding,waiting to hear from clients!\n");
addrLenA = sizeof(client_A_addr);
s_in2Size = sizeof(s_in2);
connect(socket_fd2, (struct sockaddr *) &s_in2, s_in2Size);
printf("After connect to server!\n");
// Keep listenning
for(;;) {
// Check from who we recive the message - if from cilent A
// Check for errors
//recfrom() returns the length of the message that it receives,so if the client message length that the method returns is
//equal to the message length of client A - we raffel a number between[0,1].
if( (cc = recvfrom(socket_fd1,&buff_A,sizeof(buff_A),0,(struct sockaddr*)&client_A_addr,&addrLenA))== error){
printf("No message for now, waiting...\n");
}
// For self-check ,no error occured
if (strlen(buff_A) > 0) {
printf("Client A says: %s\n", buff_A);
// Than raffel a randNum and decide what to do with it(send or delete it)
srand(time(NULL));
random = rand();
rand_num = random / RAND_MAX;
printf("rand_num: %f\n", rand_num);
printf("x: %f\n", x);
// Greater than X send it
if(rand_num > x) {
printf("Sending message From A to C\n");
// Pass the message to C
if(sendto(socket_fd2, &buff_A, sizeof(buff_A),0,(struct sockaddr*)&client_C_addr,sizeof(client_C_addr))== error){
printf("sendto()- Client C failes to send message\n");
printf("%s\n", strerror(errno));
exit(1);
}
} else {
// Drop the message
}
// Clearing the message buffer
memset(buff_A, '\0', sizeof buff_A);
}
} //end for
return 0;
}
You never fill in client_C_addr. You must tell sendto where to send the data, like:
client_C_addr.sin_family = AF_INET;
client_C_addr.sin_port = htons(port);
client_C_addr.sin_addr.s_addr = inet_addr("192.168.1.1");
Related
I'm working on a simple client/server implementation in which the client connects to the server based on the command line argument that specifies the hostname to search for a socket to connect with on (I just input localhost) and then sends a singular string that is reversed by the server, and then this reversed string is sent back to the client, and the reversed string prints. I am able to connect to the socket that lives at localhost (the client) but writing through the socket fails, and I am not sure why.
This is the server code: It has a built in reverser function that manually reverses a string and then writes it back through the socket to the client after reading in the original message that was written to the server by the client
#include <netdb.h>
#define BACKLOG 20
#include "server.h"
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define MAX_MESSAGE_LENGTH 200
char* reverse(char * word){
char *reversed;
int m=strlen(word);
reversed=(char*)(malloc(sizeof(char) * m));
printf("%d",m);
int i=0;
while (i++!=m){
char d= *(word+m-i);
strncat(reversed,&d,1);
}
return reversed;
}
void reverser_response(int sockfd,char *write_buff,char *read_buff){
read(sockfd,read_buff,sizeof(read_buff));
char *reversed_message=reverse(read_buff);
int i=0;
while (*(reversed_message)!='\0'){
write_buff[i]=*(reversed_message);
i++;
reversed_message=reversed_message+i;
}
write(sockfd,write_buff,sizeof(write_buff));
bzero(write_buff,sizeof(write_buff));
bzero(read_buff,sizeof(read_buff));
}
int main(){
int cfd,afd;
//I'm pretty sure service will be the port name
char service[NI_MAXSERV];
//hostname will be the name of the IP address
char host[NI_MAXHOST];
char read_buff[200];
char write_buff[200];
//I rmemember hints is used to set certain settings within the struct addrinfo result we create
struct addrinfo hints;
//this is used for looping through possible addrinfo structus
struct addrinfo *result, *rp;
//I think this stores the address of the client that connect with us
struct sockaddr_storage claddr;
//combined host + service name with padding of 10 bits
char addrstr[NI_MAXHOST+NI_MAXSERV+10];
memset(&hints,0,sizeof(struct addrinfo));
//socklen is the size of the socket
socklen_t socklen;
//I think AF_UNSPEC means that we can use an unspecified IP protocl: IPV4 or IPV6
hints.ai_family=AF_UNSPEC;
//stream socket
hints.ai_socktype=SOCK_STREAM;
hints.ai_next=NULL;
hints.ai_canonname=NULL;
hints.ai_addr=NULL;
//Passive: we wait for someone to join with our socket, numeric serv: use the numeric host name
hints.ai_flags=AI_PASSIVE | AI_NUMERICSERV;
//getadrrinfo: 0 is success, takes in as arguments, NULL(?) our port number, references to the hints and result addrinfo structs
//actually getaddrinfo generates a linked list of addrinfo structs for the specified host name/service name
//in this case, result is the head of the linkedlist, hints is the hints thing that sets csome conditions
if ((getaddrinfo(NULL,PORT_NUM,&hints,&result))!=0){
printf("Failed to get result pointer of address structs");
exit(EXIT_FAILURE);
}
//loop through possible addrinfo structs we can successfully create a socket at. Create socket at every possible struct. If we are successful
//in binding then quit. bind takes as arguments the socket's file descriptor, the address of the socket, and the lenth of the socket's address
//socket takes as arguments the addrinfo structu's ai_family (IPV4/6), socketpye (stream socket), and the protocol?
for (rp=result;rp;rp!=NULL){
cfd=socket(rp->ai_family,rp->ai_socktype, rp->ai_protocol);
if (cfd==-1){
continue;
}
//rp->ai_addr could be a pointer to a sockaddr_in or sockaddr_in6
if (bind(cfd,rp->ai_addr, rp->ai_addrlen)==0){
break;
}
}
if (rp==NULL){
printf("Reached end of address list without finding suitable socket address space");
exit(EXIT_FAILURE);
}
freeaddrinfo(result);
if (listen(cfd,BACKLOG)==0){
printf("Server listening....\n");
}
for (;;){
socklen=sizeof(struct sockaddr);
afd=accept(cfd,(struct sockaddr*) &claddr,&socklen);
if (afd==-1){
perror("Accept failed");
}
getnameinfo((struct sockaddr*) &claddr,socklen,
host,NI_MAXHOST,service,NI_MAXSERV,0);
snprintf(addrstr,NI_MAXSERV+NI_MAXHOST+10, "Connection received from: (%s, %s)", host,service);
printf("%s\n",addrstr);
reverser_response(afd,write_buff,read_buff);
}
close(afd);
close(cfd);
}
And this is the server implementation, which sends a message to the server, and then reads through the socket the reversed message the server sends back:
#include <netdb.h>
#include "server.h"
#include <stddef.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include "struct.h"
#define MAX_MESSAGE_LENGTH 200
void chat_function(int sockfd,char *write_buffer,char *read_buffer){
printf("\nEnter a message to send to the server. The server will reverse it, and send it back\n");
fscanf(stdin,"%s",write_buffer);
int m=strlen(write_buffer);
write_buffer[m]='\0';
int i=0;
if (write(sockfd,write_buffer,sizeof(write_buffer))!=0){
printf("Failed to send message to server\n");
exit(EXIT_FAILURE);
}
read(sockfd,read_buffer,sizeof(read_buffer));
int j=strlen(read_buffer);
read_buffer[j]='\0';
int z=0;
printf("Reversed server response:\n");
while (read_buffer[z]!='\0'){
printf("%c",read_buffer[z]);
z++;
}
}
int main(int argc, char*argv[]){
struct addrinfo hints;
struct addrinfo *result, *rp;
int cfd;
socklen_t socklen;
memset(&hints,0,sizeof(struct addrinfo));
hints.ai_family=AF_UNSPEC; //can accept IPV4 or IPV6
hints.ai_socktype=SOCK_STREAM;
hints.ai_next=NULL;
hints.ai_canonname=NULL;
hints.ai_addr=NULL;
hints.ai_flags=AI_NUMERICSERV;
char addbuff[NI_MAXSERV+NI_MAXHOST+10];
char write_buffer[MAX_MESSAGE_LENGTH];
char read_buffer[MAX_MESSAGE_LENGTH];
bzero(write_buffer,sizeof(write_buffer));
bzero(read_buffer,sizeof(read_buffer));
if (argc<2){
printf("Failed to give hostname for client");
exit(EXIT_FAILURE);
}
if ((getaddrinfo(argv[1],PORT_NUM,&hints,&result))!=0){
printf("You did not provide a legitimate host name for the client socket to search through addresses to connect to");
exit(EXIT_FAILURE);
}
for (rp=result;rp;rp=rp->ai_next){
cfd=socket(rp->ai_family,rp->ai_socktype, rp->ai_protocol);
if (cfd==-1){
continue;
}
if (connect(cfd,rp->ai_addr,rp->ai_addrlen)!=-1){
int error = 0;
socklen_t len = sizeof (error);
int retval = getsockopt (cfd, SOL_SOCKET, SO_ERROR, &error, &len);
if (retval==0){
printf("Socket successfully connected\n");
}
break;
}
}
chat_function(cfd,write_buffer,read_buffer);
if (rp==NULL){
printf("Could not connect socket to any address");
exit(EXIT_FAILURE);
}
close(cfd);
}
With the server running as a background process, I attempt to write to the server like so:
./client localhost (this connects the client to the socket that lives at localhost, the server)
and when I actually execute the client, I get back the error message I have in my code indicating the write through the socket in the client failed. Furthermore, when adding a print statement to the server's reversal method that outputs the length of the string it received as an arugment to reverse, it will be able to identify the string length of the string it received. This further confuses me - if my client is failing to even write through the socket, how is the server able to know the length of the word it's supposed to reverse?
try with send() and recv() instead of write() and read()
and the next problem is these functions most of the time fail when you want to get more than four byte so you need to do something like this:
(you shouldn't send or take all of them at once.
// allocate 4 byte memory for Memory2Send
Remained_Data = i;
j = 0
while (Remained_Data > 0){
if(Remained_Data > 4){
memcpy(Memory2Send, Memory4Data + j, 4;
send(Sock, Memory2Send, 4, 0);
j = j + 4;
Remained_Data = Remained_Data - 4;
}
else if(Remained_Data < 4){
memcpy(Memory2Send, Memory4Data + j, 4;
send(Sock, Memory2Send, Remained_Data, 0);
Remained_Data = 0;
}
try to send 4 bytes every round. you'll get all the data
and for server-side you need to receive 4 bytes every round.
// allocate 4 byte memory for Memory4Recv
j = 1;
z = 0;
while (j != 0) {
bzero(Memory4Recv,4);
recv(Sock, Memory4Recv, 4, 0);
for (i = 0; i < 4; i++){
Recv_Data[z] = Memory4Recv[i];
if (Recv_Data[z] == 0x00){
j = 0;
break;
}
z++;
}
}
put a null byte at the end of the reserved memory and if the size is equal to i send, i + 1;
if you want to communicate better, send more than 4 bytes each round and get a more reliable connection, you should do it on kernel-side. but first, get better in C and user-side socket programming then go for kernel-side.
I have two files: tcp-demo-client.c and tcp-demo-server.c
Functionality: If the connection succeeds, the client receives a simple timestamp from the server. I like to modify the code that the server only sends the timestamp if the client hits the space key. How can I do that?
(It's my first socket project)
tcp-demo-client.c:
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
int main(int argc, char **argv)
{
int ret; // return value from functions
// Check command line arguments
if (argc != 3) {
fprintf(stderr,
"Missing parameters. Usage: %s <server-name-or-ip> <server-port>\n",
argv[0]);
return 1;
}
// Address information structure
struct addrinfo aii;
// Set whole structure to 0s
memset(&aii, 0, sizeof(aii));
// A stream (TCP) connection
aii.ai_socktype = SOCK_STREAM;
// We do not care whether it is IPv4 or IPv6
aii.ai_family = PF_UNSPEC;
struct addrinfo *aio;
// Get address information.
// First parameter is host string, either hostname or numerical IPv4/IPv6 address
// Second parameter is port/service string, either as port number
// or well-known identifier, e.g. http
// So, e.g. getaddrinfo( "www.compeng.uni-frankfurt.de", "http", ... getaddrinfo( "141.2.248.1", "80", ...
// Third parameter is input address info structure (cf. above)
// Fourth parameter is output address info structure, a linked list of potential addresses
ret = getaddrinfo(argv[1], argv[2], &aii, &aio);
if (ret) {
fprintf(stderr, "Error getting address for %s:%s: %s\n",
argv[1], argv[2], gai_strerror(ret));
return 1;
}
// File descriptor for the socket
int sock = -1;
struct addrinfo *iter;
// Iterate over linked list of specified output addresses,
// use first address to which a connection can be established
for (iter = aio; iter != NULL && sock == -1; iter = iter->ai_next) {
// Create socket given the parameters from the found address info.
sock =
socket(iter->ai_family, iter->ai_socktype,
iter->ai_protocol);
if (sock < 0)
continue; // Appropriate socket could not be created, try next address
// Socket created successfully, now try to connect to remote target address
// taken from address info
ret = connect(sock, iter->ai_addr, iter->ai_addrlen);
if (ret) {
// Socket could not be connected to remote target
close(sock); // Close socket
sock = -1;
continue; // try next address
}
}
freeaddrinfo(aio); // Release address information allocated in getaddrinfo
if (sock == -1) {
// No connection at all could be established to remote target
fprintf(stderr, "Unable to establish any connection to %s:%s\n",
argv[1], argv[2]);
return 1;
}
// Maximum size of incoming message
int msglen = 100;
// Buffer for message
char buf[msglen + 1]; // One more to ensure that there is a trailing NULL char.
memset(buf, 0, msglen + 1);
ret = read(sock, buf, msglen); // Return value is amount of bytes read, -1 in case of error
printf("Data read: '%s'\n", buf);
// Clean up after us and close the socket.
close(sock);
return 0;
}
tcp-demo-server.c:
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
#define MAXPENDING 5
int main(int argc, char **argv)
{
unsigned short listen_port; // Server port */
int listen_sock; // Socket descriptor for server
int client_sock; // Socket descriptor for client
struct sockaddr_in listen_addr; // Local address */
struct sockaddr_in client_addr; // Client address */
// Check command line arguments
if (argc != 2) {
fprintf(stderr, "Missing parameters. Usage: %s <server-port>\n",
argv[0]);
return 1;
}
// Create socket for incoming connections
if ((listen_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
perror("socket() failed");
return 1;
}
// Construct local address structure
listen_port = atoi(argv[1]); // First arg: listening port number
memset(&listen_addr, 0, sizeof(listen_addr)); // Zero out structure
listen_addr.sin_family = AF_INET; // Internet address family
listen_addr.sin_addr.s_addr = htonl(INADDR_ANY); // Any incoming interface
listen_addr.sin_port = htons(listen_port); // Local port
// Bind to the local address
if (bind
(listen_sock, (struct sockaddr *)&listen_addr,
sizeof(listen_addr)) < 0) {
perror("bind() failed");
return 1;
}
// Mark the socket so it will listen for incoming connections
if (listen(listen_sock, MAXPENDING) < 0) {
perror("listen() failed");
return 1;
}
for (;;) { /* Run forever */
socklen_t addr_len = sizeof(client_addr);
// Wait for a client to connect */
if ((client_sock =
accept(listen_sock, (struct sockaddr *)&client_addr,
&addr_len)) < 0) {
perror("accept() failed");
return 1;
}
// client_sock is connected to a client
printf("New connection from %s\n",
inet_ntoa(client_addr.sin_addr));
// Create message to send
time_t t = time(NULL);
char *msg = ctime(&t);
int msglen = strlen(msg) + 1;
int ret;
// Write the whole message in one go, fail if this does not work
ret = write(client_sock, msg, msglen);
// Return value is amount of bytes written, -1 in case of error
if (ret != msglen) {
perror("Error during write");
return 1;
}
close(client_sock);
}
/* NOT REACHED */
return 1;
}
I presume you mean you want the space char as unbuffered input. For POSIX, you could use something along the lines of this to capture the keypress:
#include <termios.h>
[...]
struct termios t;
int c, r;
[...]
tcgetattr(0, &t);
t.c_lflag &= ~(ICANON | ECHO);
t.c_cc[VMIN] = 1;
tcsetattr(0, TCSANOW, &t);
c = getchar();
r = send(sock, c, 1, 0);
Have a look at this for additional information:
setvbuf not able to make stdin unbuffered
http://c-faq.com/osdep/cbreak.html
I try to create a function to open a socket (i will have multiple socket in the future) called libf_build_udp_socket. But when it comes to bind i got the error cannot assign requested address and if i bypass this bind i got an error when sending a cmd.
If i don't use my function and integrate directly the code in my main, it works perfectly.
For the explanation i have a computer under linux that have to send cmd and received log from different equipment such as signal receiver...
Here is my full code, so maybe you will better understand my goals.
/* Standard Linux headers */
#include <stdio.h> //printf
#include <string.h> //memset
#include <stdlib.h> //exit(0);
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/times.h>
#include <unistd.h>
#include <errno.h>
/* DEFINE */
#define IP_RX "192.168.0.10" //notre IP=192.168.0.5
#define BUFFLEN 1024 //Max length of buffer
#define PORT_RX 3000 //The port on which to send data
unsigned short int libf_build_udp_socket(int * udp_socket, char * server_address, unsigned short int udp_port);
int main (void)
{
/*
** Definition of the local variables.
*/
//SOCKET
struct sockaddr_in addr_rx;
int serv_len_rx=sizeof(addr_rx);
int socket_fd_rx;
unsigned short int socketStatus; /* Socket return status */
//FD
fd_set readfds;
//BUFFER & CMD
char recepbuff[BUFFLEN];
char cmd[BUFFLEN], cmd_final[BUFFLEN];
//OTHER
int i, recv;
char choice;
int loop=1;
//TIMEOUT STRUCT
struct timeval tv;
tv.tv_sec=0; /*timeout de 0sec*/
tv.tv_usec=1000; //NE MARCHE PAS SI =0
/*
** Initialisation of the local variables.
*/
memset(recepbuff, '0' ,sizeof(recepbuff)); /*pareil que bzero*/
i=0;
/*
** Creating the socket
** call socket (it creates an endpoint for communication and
** returns the socket descriptor.
** To create an UDP socket here are the param
** The protocol family should be AF_INET
** The protocol type is SOCK_DGRAM
** The protocol should beset to default ie
** DEF_PROTOCOL wich is default so 0. );
*/
//OPENING AND SETTING SOCKET RX
socketStatus = libf_build_udp_socket(&socket_fd_rx, IP_RX, PORT_RX);
if (socketStatus>0)
{
printf("Could not create the socket, code error %d\n", socketStatus);
return 0;
}
/* Messaging*/
while(1)
{
printf ("\n//Boucle %d\n", i);
//clear the buffer by filling null, it might have previously received data
memset(recepbuff, '\0' ,sizeof(recepbuff));
loop=1;
//preparing cmd
printf("Enter command :");
fgets(cmd, sizeof(cmd) , stdin);
snprintf(cmd_final, sizeof (cmd_final), cmd, "\r\n"); /*adding 0d 0a to the cmd*/
//send cmd
if ( (sendto(socket_fd_rx , cmd_final, BUFFLEN , 0 , (struct sockaddr *)&addr_rx, serv_len_rx) ) < 0 )
{
perror("ERROR > send cmd failed to wass : ");
return 0;
}
else
{
printf( "cmd send to %s:%d\n" ,inet_ntoa(addr_rx.sin_addr), ntohs(addr_rx.sin_port) );
}
//printf("\n... waiting answer from %s:%d ... \n" ,inet_ntoa(addr_rx.sin_addr), ntohs(addr_rx.sin_port) );
//strcpy(recepbuff, "whileloop");
//try to receive some data, this is a blocking call
while(loop)
{
memset(recepbuff, '\0' ,sizeof(recepbuff)); //empty buffer
FD_ZERO(&readfds);
FD_SET(socket_fd_rx, &readfds); //set testing for rx
select(socket_fd_rx+1, &readfds, NULL, NULL, &tv); //block until cmd becomes available
if(FD_ISSET(socket_fd_rx, &readfds)) //input rx available
{
//printf("Data to be read \n");
recvfrom( socket_fd_rx, recepbuff , BUFFLEN, 0, (struct sockaddr *)&addr_rx, &serv_len_rx); //recep
printf("[=> RĂ©ponse : %s\n", recepbuff);
}
else
{
loop=0;
}
}
printf(".... RĂ©ponse done from %s:%d .... \n",inet_ntoa(addr_rx.sin_addr),ntohs(addr_rx.sin_port) );
i++;
}
close(socket_fd_rx);
return 0;
}
//FONCTIONS
//OPENING 1 SETTING A SOCKET
/** libf_build_udp_socket
*
* This function creates an UDP socket.
*
* \param udp_socket socket identifier
* \param server_address IP destination address
* \param udp_port Destination UDP port
* \param server_flag TRUE to bind socket on UDP port
*
* \return 0 if successful; error code otherwise
*/
unsigned short int libf_build_udp_socket(int * udp_socket, char * server_address, unsigned short int udp_port)
{
/*
** Defining of the local variables.
*/
struct sockaddr_in serv_addr; /* Server Socket address structure*/
short int status = 0; /* internal status return*/
unsigned short int return_status = 0; /* the returnes status value */
/*
** creating the socket ;
** call socket (it creates an endpoint for communication and
** returns the socket
** descriptor. To create an UDP socket
** the parameter family is set
** to AF_INET, the type to SOCK_DGRAM, and
** the protocol to
** DEF_PROTOCOL. The socket is a global variable.);
*/
*udp_socket = socket(AF_INET, SOCK_DGRAM, 0);
if (*udp_socket < 0)
{
return_status = 1;
}
else
{
status = 1; //for future check
if (status >= 0)
{
/*
** reset the serv_addr variable
*/
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
/*
** set the sockname.sin_addr.s_addr to server address;
** sockname.sin_addr.s_addr = htonl(server address);
** set the sockname field sockname.sin_port to the used port number;
** sockname.sin_port = htons (udp port);
*/
serv_addr.sin_addr.s_addr = inet_addr(server_address);
serv_addr.sin_port = htons(udp_port);
/*
** Bind this socket to a name;
** call bind (it assigns a name or address to an unnamed socket.
** When a socket is created with socket it exists in
** a name space (address family) but has no name assigned.
** The bind requests the name, be assigned to the socket);
** If (return status signal an error)
** {
** set to return variable to error
** }
*/
status = bind(*udp_socket, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
if (status < 0)
{
printf("bind failed with %s", strerror(errno));
return_status = 2;
}
}
else
{
return_status = 3;
}
}
/*
** return status;
*/
return return_status;
}
Maybe i'm missing something essential in socket programming, i made a lot of research and try different things but it still doesn't want to work ! I would appreciate some help ! Thank you !
#include <stdio.h> /* standard C i/o facilities */
#include <stdlib.h> /* needed for atoi() */
#include <unistd.h> /* defines STDIN_FILENO, system calls,etc */
#include <sys/types.h> /* system data type definitions */
#include <sys/socket.h> /* socket specific definitions */
#include <netinet/in.h> /* INET constants and stuff */
#include <arpa/inet.h> /* IP address conversion stuff */
#include <netdb.h> /* gethostbyname */
/* this routine echos any messages (UDP datagrams) received */
#define MAXBUF 1024*1024
void echo( int sd ) {
int len,n;
char bufin[MAXBUF];
struct sockaddr_in remote;
/* need to know how big address struct is, len must be set before the
call to recvfrom!!! */
len = sizeof(remote);
while (1) {
/* read a datagram from the socket (put result in bufin) */
n=recvfrom(sd,bufin,MAXBUF,0,(struct sockaddr *)&remote,&len);
/* print out the address of the sender */
printf("Got a datagram from %s port %d\n",
inet_ntoa(remote.sin_addr), ntohs(remote.sin_port));
if (n<0) {
perror("Error receiving data");
} else {
printf("GOT %d BYTES\n",n);
/* Got something, just send it back */
sendto(sd,bufin,n,0,(struct sockaddr *)&remote,len);
}
}
}
/* server main routine */
int main() {
int ld;
struct sockaddr_in skaddr;
int length;
/* create a socket
IP protocol family (PF_INET)
UDP protocol (SOCK_DGRAM)
*/
if ((ld = socket( PF_INET, SOCK_DGRAM, 0 )) < 0) {
printf("Problem creating socket\n");
exit(1);
}
/* establish our address
address family is AF_INET
our IP address is INADDR_ANY (any of our IP addresses)
the port number is assigned by the kernel
*/
skaddr.sin_family = AF_INET;
skaddr.sin_addr.s_addr = htonl(INADDR_ANY);
skaddr.sin_port = htons(0);
if (bind(ld, (struct sockaddr *) &skaddr, sizeof(skaddr))<0) {
printf("Problem binding\n");
exit(0);
}
/* find out what port we were assigned and print it out */
length = sizeof( skaddr );
if (getsockname(ld, (struct sockaddr *) &skaddr, &length)<0) {
printf("Error getsockname\n");
exit(1);
}
/* port number's are network byte order, we have to convert to
host byte order before printing !
*/
printf("The server UDP port number is %d\n",ntohs(skaddr.sin_port));
/* Go echo every datagram we get */
echo(ld);
return(0);
}
I am new to linux and have booted linux on my zedboard following some tutorials. Now I have to make an application program that runs udp echo server over it and I got this program over internet and now I am confused whether the arpa/inet.h netinet/in.h are already available in linux or do we have to make those? and How and where should I give the ip address and port numbers?
I'm tyring to create a server client connection but for some reason when I run the server code, it'll just give me the prompt, nothing happens. I put a printf as the first thing in the main function but even that doesn't happen. What could be executed before the main? I don't think I have anything that could cause a problem.
#include "md5.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <pthread.h>
void *handle_connection (void *); //gets a connection identifier and handles that incoming connection
int verify_password (char s[]); // verifies if the input password is correct
int main(int argc, char *argv[])
{
pthread_t connected;
pthread_attr_t attributes;
int listenfd = 0, conn_id = 0; // the listening socket identifier and current connection identifier
//A: Creates the master socket
listenfd = socket (PF_INET, SOCK_STREAM, 0);
//B: the struct variable that keeps the socket address
struct sockaddr_in sad; /* structure to hold an IP address */
struct sockaddr_in cad;
struct hostent *ptrh; /* pointer to a host table entry */
socklen_t alen;
//B: initialization of socket address variable
memset ((char *)&sad, 0, sizeof(sad)); /* clear sockaddr structure */
sad.sin_family = AF_INET; /* set family to Internet */
sad.sin_addr.s_addr = INADDR_ANY; /* set the local IP address */
sad.sin_port = htons((u_short) 5000); /* set the port number */
//C: binds the socket to its address
bind (listenfd, (struct sockaddr *)&sad, sizeof(sad));
//D: starts listening on that socket
listen (listenfd, 100000);
while (1) // listens for incoming connections until program exits manually
{
int conn_id = 0;
//E: Wait for a connection request and accept it
conn_id = accept (listenfd, (struct sockaddr *)&cad, &alen);
//F: if the connection has been established it creates a thread that handles the connection
if (conn_id != -1)
{
pthread_attr_init (&attributes);
pthread_attr_setdetachstate (&attributes, PTHREAD_CREATE_DETACHED);
pthread_create (&connected, &attributes, (void *) handle_connection, &conn_id);
}
}
}
void *handle_connection(void *arg)
{
int conn_id = *(int *) arg;
char recv_buff[1024]; // the buffer that is used for keeping the data read from the socket
int n = 0; // number of characters read from socket
//G: read from connection into the buffer and checks if recieving data was successful
if (n = recv (conn_id, recv_buff, 1024, 0) <= 0)
{
printf ("Error Reading");
}
//H: verifies if the password is correct and sends T if the password is correct and F otherwise
if (verify_password (recv_buff) == 1)
{
if (send (conn_id, "T", 1, 0) < 1) {
printf ("Error Sending");
}
} else {
if (send (conn_id, "F", 1, 0) < 1) {
printf ("Error Sending");
}
}
//I: closes the connection
close (conn_id);
}
int verify_password(char s[])
{
char md5_hashed_password[33] ="24af484e92082ad450a63a69f924f10a"; // The password of server hashed by MD5
char md5_hashed_text[33]; // Keeps the MD5 hashed text of input text
size_t len = strlen(s);
md5 ((uint8_t*)s, len, md5_hashed_text); //Finds the MD5 hashed of input text
if (strncmp (md5_hashed_text, md5_hashed_password, 32) == 0) //If the hashed value of the input value and the
return 1; // password is same the password is accepted
return 0;
}