Program doesn't enter the main function? - c

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;
}

Related

Need to use socket programming to write an echo server that utilizes the TCP/IP protocol, but my connection to the server is failing

Both programs compile, and I'm able to successfully create a socket, but the connection to the server fails. This is basically a TCP echo program.
PS. I'm new here so IDK how to use this, I don't have much programming experience so bare with me.
tcp echo client-1
tcp echo client-2
tcp echo server-1
tcp echo server-2
Compiling/Running server gives me: Server not fully implemented...
Compiling/Running client gives me: Socket successfully created..Error: connection to the server failed!
**// TCP echo client program**
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main (int argc, char* argv[ ]) // Three arguments to be checked later
{
struct sockaddr_in servAddr; // Server socket address data structure
char *servIP = argv[1]; // Server IP address from command line
int servPort = atoi(argv[2]); // Server port number from command line
char *message = argv[3]; // Message specified on the command line
char buffer [512 + 1];
char* ptr = buffer;
int len;
int max_len = sizeof(buffer);
int sock_descrip;
// Check for correct number of command line arguments
if(argc != 4) {
printf("tcp-echo-client [IP address] [Port] [Message]\n");
exit (1);
}
// Populate socket address for the server
memset (&servAddr, 0, sizeof(servAddr)); // Initialize data structure
servAddr.sin_family = AF_INET; // This is an IPv4 address
servAddr.sin_addr.s_addr = inet_addr(servIP); // Server IP address
servAddr.sin_port = servPort; // Server port number
// Create a TCP socket stream
int sock;
if ((sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
printf("Error: socket creation failed!\n");
exit (1);
}
else
printf("Socket successfully created..\n");
// Connect to the server
if ((connect (sock, (struct sockaddr*)&servAddr, sizeof(servAddr))) == -1) {
printf("Error: connection to the server failed!\n");
exit (1);
}
else
printf("Connected to the server..\n");
// Send data to the server...
send(sock_descrip, message, strlen(message),0);
int x;
while ((x = recv(sock_descrip, ptr, max_len,0))>0)
{
ptr += x;
max_len -= x;
len += x;
}
buffer[len] = '\0';
printf("Echoed string received: %s %c", buffer,*message);
// Receive data back from the server..
// Loop while receiving data...
// print data...
// end-while loop
// Close socket
close (sock);
// Stop program
exit (0);
} // End main
**//TCP Echo server program**
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define BUFLEN 512 // Maximum length of buffer
#define PORT 9988 // Fixed server port number
int main (void)
{
struct sockaddr_in server_address; // Data structure for server address
struct sockaddr_in client_address; // Data structure for client address
int client_address_len = 0;
char buffer [512];
char* ptr = buffer;
int len;
int max_len = BUFLEN;
int sock_descrip;
// Populate socket address for the server
memset (&server_address, 0, sizeof (server_address)); // Initialize server address data structure
server_address.sin_family = AF_INET; // Populate family field - IPV4 protocol
server_address.sin_port = PORT; // Set port number
server_address.sin_addr.s_addr = INADDR_ANY; // Set IP address to IPv4 value for loacalhost
// Create a TCP socket; returns -1 on failure
int listen_sock;
if ((listen_sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
printf("Error: Listen socket failed!\n");
exit (1);
}
// Bind the socket to the server address; returns -1 on failure
if ((bind(listen_sock, (struct sockaddr *)&server_address, sizeof (server_address))) == -1) {
printf("Error: binding failed!\n");
exit (1);
}
printf("Server not fully implemented...\n");
// Listen for connections...
int wait_size;
if (listen(listen_sock, wait_size) == -1)
{
printf("Error: listening failed!\n");
exit(1);
}
for(;;)
{
if(sock_descrip=accept(listen_sock,(struct sockaddr *)&client_address, &client_address_len) == -1)
{
printf("Error: accepting failed!\n");
exit(1);
}
int x;
while ((x = recv(sock_descrip, ptr, max_len, 0)) > 0)
{
ptr += x;
max_len -= x;
len += x;
}
send(sock_descrip,buffer,len,0);
}
// Echo data back to the client...
close (listen_sock); // Close descriptor referencing server socket
} // End main
You need parentheses around the assignment:
if(
(sock_descrip=accept(listen_sock,(struct sockaddr *)&client_address, &client_address_len))
== -1)

C Socket sendto Invalid argument error

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");

TCP-Socket Programming in C

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

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);
}
}

Problem in udp socket programing in c

I complile the following C code of UDP client
after I run './udpclient localhost 9191' in terminal.I put "Enter Text= " as Hello, but it is showing error in sendto as below:
Enter text: hello
hello
: error in sendto()guest-1SDRJ2#md-K42F:~/Desktop$
"
Note: I open 1st the server port as below in other terminal
./server 9191.
I beleive there is no error in server code. The udp client is not passing message to server. If I don't use thread , the message is passing .But I have to do it by thread.
UDP client Code:
/* simple UDP echo client */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <pthread.h>
#define STRLEN 1024
static void *readdata(void *);
static void *writedata(void *);
int sockfd, n, slen;
struct sockaddr_in servaddr;
char sendline[STRLEN], recvline[STRLEN];
int main(int argc, char *argv[]) {
pthread_t readid,writeid;
struct sockaddr_in servaddr;
struct hostent *h;
if(argc != 3) {
printf("Usage: %s <proxy server ip> <port>\n", argv[0]);
exit(0);
}
/* create hostent structure from user entered host name*/
if ( (h = gethostbyname(argv[1])) == NULL) {
printf("\n%s: error in gethostbyname()", argv[0]);
exit(0);
}
/* create server address structure */
bzero(&servaddr, sizeof(servaddr)); /* initialize it */
servaddr.sin_family = AF_INET;
memcpy((char *) &servaddr.sin_addr.s_addr, h->h_addr_list[0], h->h_length);
servaddr.sin_port = htons(atoi(argv[2])); /* get the port number from argv[2]*/
/* create a UDP socket: SOCK_DGRAM */
if ( (sockfd = socket(AF_INET,SOCK_DGRAM, 0)) < 0) {
printf("\n%s: error in socket()", argv[0]);
exit(0);
}
pthread_create(&readid,NULL,&readdata,NULL);
pthread_create(&writeid,NULL,&writedata,NULL);
while(1)
{
};
close(sockfd);
}
static void * writedata(void *arg)
{
/* get user input */
printf("\nEnter text: ");
do {
if (fgets(sendline, STRLEN, stdin) == NULL) {
printf("\n%s: error in fgets()");
exit(0);
}
/* send a text */
if (sendto(sockfd, sendline, sizeof(sendline), 0, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) {
printf("\n%s: error in sendto()");
exit(0);
}
}while(1);
}
static void * readdata(void *arg)
{
/* wait for echo */
slen = sizeof(servaddr);
if ( (n = recvfrom(sockfd, recvline, STRLEN, 0, (struct sockaddr *) &servaddr, &slen)) < 0) {
printf("\n%s: error in recvfrom()");
exit(0);
}
/* null terminate the string */
recvline[n] = 0;
fputs(recvline, stdout);
}
The problem is that you're using the same sockaddr struct (servaddr) for both the sendto and revfrom calls. The recvfrom happens first, so it clears out servaddr in preparation for writing in the source address of the received packed (once it receives one -- that thread is still blocked in the kernel waiting for a packet). Then, when the sendto call occurs, the sockaddr is all zeros, so it immediately returns EINVAL.
You may be getting confused by the fact that the sockaddr argument to recvfrom is an OUTPUT, not an input -- it gets filled in with the source address of the packet that is received (which could be from anywhere). If you want to only receive packets from a particular place (the server?), you need to check the address after the recvfrom returns and toss the packet if it comes from somewhere else, looping back to recvfrom again.

Resources