gcc: wrong behaviour after new variable was added - c

I am writing simple programs: server and client. You know, I am just learning all these stuff.
I added new variable (fileUp in server.c) and the client just crashed. I debugged it with gdb. The client can't read anything from the socket. Without that one variable works fine.
I did compile these programs with both gcc and g++ with -Wall. No errors, no warnings.
Programs are as simple as they can be. I don't understand what is wrong.
Any hint'll be appreciated.
server.c
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char **argv) {
struct sockaddr_in address, client;
int s = socket(AF_INET, SOCK_STREAM, 0);
memset(&address, 0, sizeof(address));
address.sin_family = AF_INET;
address.sin_addr.s_addr = htonl(INADDR_ANY);
#define PORT 54321
address.sin_port = htons(PORT);
if(bind(s, (struct sockaddr *)&address, sizeof(address))<0) {
perror("nie udał się bind");
exit(-1);
}
if(listen(s, 5)<0) {
perror("nie udał się listen");
exit(-1);
}
socklen_t client_len;
int c = accept(s, (struct sockaddr *)&client, &client_len);
int file = open("../data", O_RDONLY);
if(file<0) {
perror("nie udało się otworzyć pliku");
exit(-1);
}
#define MAX 1024
char buf[MAX];
int n = read(file, buf, MAX);
int fileUp = n;
do {
write(c, buf, MAX);
buf[n-1] = '\0';
printf("%d: %s\n", n, buf);
/*fileUp += n;
printf("pobrano: %d\n", fileUp);*/
n = read(file, buf, MAX);
getchar();
} while(n != 0);
close(c);
close(s);
return 0;
}
client.c
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char **argv) {
struct sockaddr_in address;
int s = socket(PF_INET, SOCK_STREAM, 0);
memset(&address, 0, sizeof(address));
address.sin_family = AF_INET;
#define PORT 54321
address.sin_port = htons(PORT);
if(inet_pton(AF_INET, argv[1], &address.sin_addr) <=0) {
perror("podano nieprawidłowy adres");
exit(-1);
}
if(connect(s, (struct sockaddr *)&address, sizeof(address))<0) {
perror("nie można się połączyć");
exit(-1);
}
#define MAX 1024
char buf[MAX];
int n = read(s, buf, MAX);
int fileDown = n;
do {
buf[n-1] = '\0';
printf("%d: %s\n", n, buf);
n = read(s, buf, MAX);
fileDown += n;
printf("pobrano: %d\n", fileDown);
} while(n != 0);
close(s);
return 0;
}

socklen_t client_len; should be socklen_t client_len = sizeof(client);
The stack layout will change when you add your new variable - so the uninitialized value in client_len just happened to work before, it doesn't after - most likely making your accept call fail, and then you're trying to write to an invalid FD.
You should of course also check the return value of accept

Related

Sending binary data between client and server

I am implementing a simple server-client inter-process communication by sending data in binary format from the client to the server. The program is simple: it sends an unsigned number from 1 to 5, once at a time, in binary format. The server reads in the these binary data and converts it back to an unsigned int. However, when I tried to read in on the server size, my binary data was changing. How can I make the reading protocol to read in the data in a format that I sent. I appreciate all helps that I can get! Thank you.
Here is my implementation of the server:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <limits.h>
#include <netdb.h>
#define BUFFER_SIZE 10
int main(int argc, char *argv[])
{
int serv_sock, ret, data_socket;
socklen_t client_sock;
struct sockaddr_in serv_addr;
struct sockaddr_in client_addr;
// char buffer[BUFFER_SIZE];
uint32_t buffer = 0;
FILE *fp;
char hostname[HOST_NAME_MAX];
char ipaddr[INET_ADDRSTRLEN];
char port[6];
serv_sock = socket(AF_INET, SOCK_STREAM, 0);
if (serv_sock == -1)
{
perror("socket");
exit(1);
}
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(35000);
ret = bind(serv_sock, (const struct sockaddr *)&serv_addr, sizeof(serv_addr)); // bind socket to server address
if (ret == -1)
{
printf("bind error: %s\n", strerror(errno));
exit(1);
}
listen(serv_sock, 20);
// get hostname
gethostname(hostname, HOST_NAME_MAX);
// get ip address
getnameinfo((struct sockaddr *)&serv_addr, sizeof(serv_addr), ipaddr, INET_ADDRSTRLEN, port, 6, NI_NUMERICHOST | NI_NUMERICSERV);
// get port number
printf("Server %s is running on %s : %s\n", hostname, ipaddr, port);
while (1)
{
data_socket = accept(serv_sock, (struct sockaddr *)&client_addr, &client_sock);
// print client host name and ip address
getnameinfo((struct sockaddr *)&client_addr, sizeof(client_addr), hostname, HOST_NAME_MAX, port, 6, NI_NUMERICHOST | NI_NUMERICSERV);
printf("Client %s is connected to %s : %s\n", hostname, ipaddr, port);
if (data_socket == -1)
{
printf("accept error: %s\n", strerror(errno));
exit(1);
}
while (1){
int n = read(data_socket, &buffer, sizeof(uint32_t));
if (n == -1)
{
printf("read error: %s\n", strerror(errno));
exit(1);
}
if (n == 0)
{
break;
}
uint32_t temp = ntohl(buffer);
printf("%d\n", temp);
}
close(data_socket);
// if (!strncmp(buffer, "418", sizeof(buffer)))
// {
// break;
// }
}
close(serv_sock);
return 0;
}
Client implimentation:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <inttypes.h>
int main(int argc, char *argv[])
{
struct sockaddr_in addr;
int ret, data_socket, i;
unsigned int num_arr[5] = {1, 2, 3, 4, 5};
char send_str[100];
data_socket = socket(AF_INET, SOCK_STREAM, 0);
if (data_socket == -1)
{
perror("socket");
exit(1);
}
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = htons(35000);
ret = connect(data_socket, (const struct sockaddr *)&addr, sizeof(addr));
if (ret == -1)
{
printf("connect error: %s\n", strerror(errno));
exit(1);
}
for (i = 0; i < 5; i++)
{
// sprintf(send_str, "%d\n", num_arr[i]);
// now send data as binary data
uint32_t num = htonl(num_arr[i]);
printf("%d\n", num);
printf("%d\n", ntohl(num));
write(data_socket, &num, sizeof(num));
write(data_socket, "\n", 1);
}
uint32_t delimiter = htonl(-1);
write(data_socket, &delimiter, sizeof(uint32_t));
if (argc == 2)
{
if (strncmp(argv[1], "quit", 4) == 0)
{
printf("User quits\n");
ret = write(data_socket, "418\n", 4);
}
else
{
printf("Wrong Argument\n");
}
}
close(data_socket);
return 0;
}

C Socket TCP, send array to server and response back to client in loop

I'm very new to socket and TCP, I'm trying to send an array of Int to the server, do some sorting and calculating, then send back the result to the client and repeat.
I tried a few different ways, I either got the result after I close the client or got into a infinite loop.
What is the proper way to keep reading from the client until the client hit EOF?
Here is my server code.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main(int argc, char const *argv[]) {
struct sockaddr_in server, client;
int sock, csock, readSize, addressSize;
char buf[256];
bzero(&server, sizeof(server));
server.sin_family = PF_INET;
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_port = htons(5999);
sock = socket(PF_INET, SOCK_STREAM, 0);
bind(sock, (struct sockaddr*)&server, sizeof(server));
listen(sock, 5);
addressSize = sizeof(client);
csock = accept(sock, (struct sockaddr *)&client, &addressSize);
int values[5];
while (read(csock, values, sizeof(values))) {
// Some sorting and calculating here
for (int i = 0; i < 5; i++) {
printf("%d ", values[i]);
}
}
close(sock);
return 0;
}
And here is my client code.
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main(int argc, char const *argv[]) {
struct sockaddr_in server;
char buf[256];
int sock;
bzero(&server, sizeof(server));
server.sin_family = PF_INET;
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_port = htons(5999);
sock = socket(PF_INET, SOCK_STREAM, 0);
connect(sock, (struct sockaddr *)&server, sizeof(server));
while (1) {
int values[5] = {0};
for (int i = 0; i < 5; i++)
scanf("%d", &values[i]);
write(sock, values, sizeof(values));
}
return 0;
}
Thanks for your help!
On Linux, I observed that if client is terminated with Ctrl-C, then server exits when read() returns 0 to signify EOF. If client is given a Ctrl-D, the stream's error state is set and this and all future scanf calls fail without setting values. This means values retain their zero initialization, which is sent to server in each iteration of the infinite loop.
Per #user207421, recv() which I guess how read() is implemented may return on error on windows to signify and errors. In this case, server would loop with the original code.
In either case, I added error checking for most of calsl (you should also add it for inet_addr()), and the server will terminate if read() returns either -1 or 0:
server:
#include <arpa/inet.h>
#include <errno.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/socket.h>
#include <unistd.h>
int main(int argc, char const *argv[]) {
struct sockaddr_in server, client;
int sock, csock;
socklen_t addressSize;
bzero(&server, sizeof(server));
server.sin_family = PF_INET;
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_port = htons(5999);
sock = socket(PF_INET, SOCK_STREAM, 0);
if(sock == -1) {
printf("socket: %s\n", strerror(errno));
return 1;
}
if(bind(sock, (struct sockaddr*)&server, sizeof(server)) == -1) {
printf("bind: %s\n", strerror(errno));
return 1;
}
if(listen(sock, 5) == -1) {
printf("listen: %s\n", strerror(errno));
return 1;
}
addressSize = sizeof(client);
csock = accept(sock, (struct sockaddr *)&client, &addressSize);
if(csock == -1) {
printf("listen: %s\n", strerror(errno));
return 1;
}
int values[5];
ssize_t n;
while ((n = read(csock, values, sizeof(values)))) {
printf("read %zd\n", n);
if(n <= 0) break;
for (int i = 0; i < n / sizeof(*values); i++) {
printf("%d ", values[i]);
}
printf("\n");
}
close(sock);
return 0;
}
and client:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
int main(int argc, char const *argv[]) {
struct sockaddr_in server;
char buf[256];
int sock;
bzero(&server, sizeof(server));
server.sin_family = PF_INET;
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_port = htons(5999);
sock = socket(PF_INET, SOCK_STREAM, 0);
if(sock == -1) {
printf("socket: %s\n", strerror(errno));
return 1;
}
if(connect(sock, (struct sockaddr *)&server, sizeof(server)) == -1) {
printf("connect: %s\n", strerror(errno));
return 1;
}
while (1) {
int values[5] = {0};
for (int i = 0; i < 5; i++) {
int r = scanf("%d", &values[i]);
if(r == EOF) {
return 0;
}
}
ssize_t n = write(sock, values, sizeof(values));
if(n == -1) {
printf("write: %s\n", strerror(errno));
return 1;
}
printf("wrote %zd\n", n);
}
return 0;
}
and here is the output from the server:
$ ./server
read 20 bytes
1 2 3 4 5
and the client (note; client doesn't send partial data):
$ ./client
1
2
3
4
5
wrote 20
1

modify c socket program to send file from server to client

Modify the following socket program and let the server send a file to the client.
I'm stuck with this i can't figure this out.
below is the server and client that where given to me. right now the server will send the client the time stamp.
Socket Server Example (server.c)
#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 <time.h>
int main(int argc, char *argv[])
{
int listenfd = 0, connfd = 0;
struct sockaddr_in serv_addr;
char sendBuff[1025];
time_t ticks;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&serv_addr, '0', sizeof(serv_addr));
memset(sendBuff, '0', sizeof(sendBuff));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(5000);
bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
listen(listenfd, 10);
while(1)
{
connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);
ticks = time(NULL);
snprintf(sendBuff, sizeof(sendBuff), "%.24s\r\n",
ctime(&ticks));
write(connfd, sendBuff, strlen(sendBuff));
close(connfd);
sleep(1);
}
}
Socket Client Example (client.c)
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
int sockfd = 0, n = 0;
char recvBuff[1024];
struct sockaddr_in serv_addr;
if(argc != 2)
{
printf("\n Usage: %s <ip of server> \n",argv[0]);
return 1;
}
memset(recvBuff, '0',sizeof(recvBuff));
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Error : Could not create socket \n");
return 1;
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(5000);
if(inet_pton(AF_INET, argv[1], &serv_addr.sin_addr)<=0)
{
printf("\n inet_pton error occured\n");
return 1;
}
if( connect(sockfd, (struct sockaddr *)&serv_addr,
sizeof(serv_addr)) < 0)
{
printf("\n Error : Connect Failed \n");
return 1;
}
while ( (n = read(sockfd, recvBuff, sizeof(recvBuff)-1)) > 0)
{
recvBuff[n] = 0;
if(fputs(recvBuff, stdout) == EOF)
{
printf("\n Error : Fputs error\n");
}
}
if(n < 0)
{
printf("\n Read error \n");
}
return 0;
}
If you don't want to or can't read the whole content of the file you wish to send at once into memory, use a loop with your buffer:
#include <fcntl.h>
if (argv[1]) // or whereever you get the file name from
{
int fd = open(argv[1], O_RDONLY);
if (fd < 0) perror(argv[1]);
else
{
ssize_t n;
while (n = read(fd, sendBuff, sizeof sendBuff), n > 0)
if (send(connfd, sendBuff, n, MSG_NOSIGNAL) < 0)
{ perror("send"); break; }
close(fd);
if (n < 0) perror("read");
}
}
In the client use a similar loop. Be aware that the file might contain NUL characters, so functions like fputs, operating on C strings, are inept.
while ((n = read(sockfd, recvBuff, sizeof recvBuff)) > 0)
if (write(1, recvBuff, n) < 0) perror("write");
Read the content of the file you wish to send, and save it into a string:
char *loadFileContent(char *fileName, size_t *len){
FILE* input_file = fopen(fileName, "rb");
size_t stat;
if(!input_file){
OCSP_ERR_INDEX = OCSP_LOG_ERR_load_file_fail;
return NULL;
}
fseek(input_file, 0, SEEK_END);
long int input_file_size = ftell(input_file);
rewind(input_file);
char *file_contents = malloc((input_file_size + 1) * (sizeof(char)));
stat = fread(file_contents, sizeof(char), (size_t) input_file_size, input_file);
if(stat<1){
OCSP_ERR_INDEX = OCSP_LOG_ERR_load_file_fail;
return NULL;
}
fclose(input_file);
file_contents[input_file_size] = 0;
*len = (size_t) input_file_size;
return file_contents;
}
In your code, modify the line in server that is supposed to send response to client.
So this line write(connfd, sendBuff, strlen(sendBuff)); becomes:
size_t len;
char *text = loadFileContent("myfile.txt", &len);
write(connfd, text, len);

C - UDP Client not completing SendTo to Echo Server

I'm trying to complete a simple echo server. The goal is to repeat back the message to the client. The server and client both compile. The server runs, you just need to give it a port to run on. The client has the address, the port, and the message. When the client goes through the program to the sendto section, it stop and waits there. My goal it to have it sent to the server, and the server to send it back.
I believe that the server works, or it least is in the mode to receive as it enters the while loops to do that. That part can send notes back that it works.
For the client, I've tried sending the argument directly, but also through a c-string. I've tried one hard coded in, and none of them have worked. I've been at it for many hours, so I decided to ask for help because I can't think of anything else as a newbie.
Client
//argv[1] address, argv[2] port, argv[3] message
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
int main(int argc, char *argv[]){
int BUF_LEN;
for (BUF_LEN = 0; argv[3][BUF_LEN] != '\0'; BUF_LEN++){
// printf("BUF_LEN = %i\n", BUF_LEN);
}
int s, n, port_no, r;
struct sockaddr_in server_addr;
char *haddr, *message;
char buf[BUF_LEN+1];
printf("Variables created\n");
s = socket(AF_INET, SOCK_DGRAM, 0); // create a socket for UDP
printf("Socket created as s: %i\n", s);
bzero((char *)&server_addr, sizeof(server_addr)); // clear
server_addr.sin_family = AF_INET; //IPv4 Internet family
server_addr.sin_addr.s_addr = inet_addr(argv[1]); //server address
server_addr.sin_port = htons(atoi(argv[2])); // server port number
printf("Server addr complete\n");
//Bind() - Not necessary
printf("Bind skipped\n");
//sendto()
r = sendto(s, argv[3], strlen(argv[3]), 0, (struct sockaddr *)&server_addr, BUF_LEN);
printf("Message Sent");
//recvfrom()
n = recvfrom (s, buf, BUF_LEN, 0, (struct sockaddr *)&server_addr, &BUF_LEN);
printf("Message Received: %s\n", buf);
close(s);
}
Server
//Argv[1] : port number
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
int main(int argc, char *argv[]){
int n;
int MAXLINE = 512;
int sock_server, sock_client, r, len;
char buf[MAXLINE];
struct sockaddr_in my_addr, client_addr;
//printf("Variables created\n");
sock_server = socket (PF_INET, SOCK_DGRAM, 0);
//printf("Socket created\n");
if (sock_server < 0){
perror("Bind failed");
exit(1);
}
bzero(&my_addr, sizeof(my_addr)); // clear
my_addr.sin_family = AF_INET; //Address Family INET
my_addr.sin_port = htons(atoi(argv[1])); //Server port number
my_addr.sin_addr.s_addr = htonl(INADDR_ANY); // Accept from anywhere
//printf("Addresses created\n");
r = bind(sock_server, (struct sockaddr*)(&my_addr), sizeof(my_addr));
if (r < 0) {
perror("Bind failed");
exit(1);
}
printf("Read to receive\n");
while(1) {
//printf("First while loop\n");
len = sizeof(struct sockaddr_in);
//recvfrom()
n = recvfrom (sock_client, buf, MAXLINE, 0, (struct sockaddr *)&client_addr, &len);
while (n > 1){
printf("Second while loop\n");
printf("Message Received: %s\n", buf);
//sendto()
sendto(sock_client, buf, n, 0, (struct sockaddr *)&client_addr, len);
n = 0;
}
}
close(sock_client); //close the client socket
//printf("Connection sock_client Closed");
}
Here is the fixed version of the client using sizeof(server_addr) in the client call of sendto:
//argv[1] address, argv[2] port, argv[3] message
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
int main(int argc, char *argv[]){
int BUF_LEN;
for (BUF_LEN = 0; argv[3][BUF_LEN] != '\0'; BUF_LEN++){
// printf("BUF_LEN = %i\n", BUF_LEN);
}
int s, n, port_no, r;
struct sockaddr_in server_addr;
char *haddr, *message;
char buf[BUF_LEN+1];
printf("Variables created\n");
s = socket(AF_INET, SOCK_DGRAM, 0); // create a socket for UDP
printf("Socket created as s: %i\n", s);
bzero((char *)&server_addr, sizeof(server_addr)); // clear
server_addr.sin_family = AF_INET; //IPv4 Internet family
server_addr.sin_addr.s_addr = inet_addr(argv[1]); //server address
server_addr.sin_port = htons(atoi(argv[2])); // server port number
printf("Server addr complete\n");
//Bind() - Not necessary
printf("Bind skipped\n");
r = sendto(s, argv[3], strlen(argv[3]), 0, (struct sockaddr *)&server_addr, sizeof(server_addr));
printf("Message Sent");
n = recvfrom (s, buf, BUF_LEN, 0, (struct sockaddr *)&server_addr, &BUF_LEN);
printf("Message Received: %s\n", buf);
close(s);
}

Error in recvfrom in C socket programming?

Sorry for my not perfet english
I have to implement reliable communication using UDP protocol; for start, i'm tring realize a simple program; a client send a message to server with NULL in buffer; the servers understands it as a request, then sends to client response, which is a number;
code client:
/*
* newClient.c
*
* Created on: 22 lug 2017
* Author: claudio
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SERV_PORT 5193
#define MAXLINE 1024
void err_exit(char* str)
{
perror(str);
exit(EXIT_FAILURE);
}
int request_to_server(int sockfd,int* x,struct sockaddr_in addr)
{
int n;
if(sendto(sockfd, NULL, 0, 0, (struct sockaddr *) &addr, sizeof(addr)) < 0)
err_exit("sendto\n");
n = recvfrom(sockfd,(char*)x,sizeof(int),0,NULL,NULL);
if (n < 0) {
perror("errore in recvfrom");
exit(1);
}
if(n > 0) {
printf("client received: %d\n",*(int*)x);
}
return 1;
}
int main(int argc, char *argv[ ]) {
int sockfd;
struct sockaddr_in servaddr;
int x;
if (argc != 2) {
fprintf(stderr, "utilizzo: daytime_clientUDP <indirizzo IP server>\n");
exit(1);
}
if ((sockfd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { /* crea il socket */
perror("errore in socket");
exit(1);
}
memset((void *)&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) {
err_exit("error in inet_pton for %s");
}
if(request_to_server(sockfd,&x,servaddr))
printf("client received %d from server\n",x);
exit(EXIT_SUCCESS);
}
this is server code:
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define SERV_PORT 5193
#define MAXLINE 1024
void err_exit(char* str)
{
perror(str);
exit(EXIT_FAILURE);
}
int generate_casual()
{
int x = random()%1000 + 1; //number between 1 and 1000
return x;
}
void listen_request(int sockfd,char* buff,struct sockaddr_in* addr,socklen_t* len)
{
struct sockaddr_in servaddr = *addr;
socklen_t l = *len;
printf("listening request\n");
if ( (recvfrom(sockfd, buff, MAXLINE, 0, (struct sockaddr *)&servaddr, &l)) < 0){
printf("errno code: %d\n",errno);
err_exit("recvfrom\n");
}
*addr = servaddr;
*len = l;
return;
}
int main(int argc, char **argv)
{
(void) argc;
(void) argv;
int sockfd;
socklen_t len;
struct sockaddr_in addr;
char buff[MAXLINE];
srand(time(NULL));
memset((void *)&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(SERV_PORT); /* numero di porta del server */
if ((sockfd = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
err_exit("errore in socket");
if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("errore in bind");
exit(1);
}
listen_request(sockfd,buff,&addr,&len);
int n_ack = generate_casual();
//char* p =(char*)&n_ack;
if (sendto(sockfd, (char*)&n_ack, sizeof(int), 0, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
err_exit("sendto");
}
printf("server: client is connected\n");
return 0;
}
when i run, sometimes client receives correctly number; but sometimes i have an error on recvfrom with msg "Invalid argument" ed errno code is 22;
why this?I have no idea in which case it runs and when it doesn't work, code is the same..

Resources