After the user as entered data it writes out a part of the data entered before the data just enetered if that makes sense? I've only included a snippet, but can anyone see any reason why it would reply multiple times?
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<arpa/inet.h> //inet_addr
#include<unistd.h> // write
#include<pthread.h> // For Threading
#include<wiringPi.h>
void *connection_handler(void *);
void lightLED(int pin,int status);
int maxConnections = 1;
int totalConnections = 0;
int main(int argc , char *argv[])
{
int socket_desc , new_socket , c, *new_sock;
struct sockaddr_in server , client;
char *message;
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 8888 );
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
puts("bind failed");
}
puts("bind done");
//Listen
listen(socket_desc , 3);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
while( (new_socket = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) )
{
if(new_socket > 0)
{
if(totalConnections < maxConnections){
totalConnections++;
}
else
{
message = "Sorry Maximum Users Reached\n";
write(new_socket,message,strlen(message));
puts("Too many Users");
close(new_socket);
continue;
}
}
puts("Connection Accepted");
char *client_ip = inet_ntoa(client.sin_addr);
int client_port = ntohs(client.sin_port);
printf("ClientIP:%s\n",client_ip);
message = "Hello you have been accepted!\n";
write(new_socket, message , strlen(message));
pthread_t sniffer_thread;
new_sock = malloc(1);
*new_sock = new_socket;
if(pthread_create( &sniffer_thread, NULL , connection_handler , (void*) new_sock) <0)
{
perror("Could not create thread");
return 1;
}
puts("Handler Assigned");
}
if (new_socket<0)
{
perror("accept failed");
return 1;
}
return 0;
}
void *connection_handler(void *socket_desc)
{
int sock = *(int*)socket_desc;
int read_size;
char *message , client_message[2000];
message = "Greeting! I am your Connection Handler\n";
write(sock , message,strlen(message));
message = "What do you want to do\n";
write(sock,message,strlen(message));
while( (read_size = recv(sock , client_message , 2000 , 0)) > 0)
{
write(sock , client_message , strlen(client_message));
printf("User Entered:%s\n",client_message);
int pin = client_message[0]-'0';
int status = client_message[1]-'0';
lightLED(pin,status);
}
if(read_size == 0)
{
puts("Client Disconnected\n");
fflush(stdout);
totalConnections--;
}else if(read_size == -1)
{
perror("recv Failed");
}
free(socket_desc);
return 0;
}
void lightLED(int pin,int status)
{
char message;
if(wiringPiSetup() == -1){
puts("wiringPi Error");
exit(1);
}
//pinMode(pin,OUTPUT);
printf("Changing LED Pin- %d Status- %d\n",pin,status);
//digitalWrite(pin,status);
}
First pass
I'm not sure what problem you're seeing. I've taken your code (which was in pretty good shape — well done; I've looked at a lot of code with many worse problems in it) and compiled it and run it and it seemed to work for me:
$ nc localhost 8888
Connection Accepted
ClientIP:127.0.0.1
Handler Assigned
Hello you have been accepted!
Greeting! I am your Connection Handler
What do you want to do
01
User Entered:01
Changing LED Pin- 0 Status- 1
01
21
User Entered:21
Changing LED Pin- 2 Status- 1
21
31
User Entered:31
Changing LED Pin- 3 Status- 1
31
we wish you a merry Christmas
User Entered:we wish you a merry Christmas
Changing LED Pin- 71 Status- 53
we wish you a merry Christmas
Client Disconnected
$
The code as run was:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>
//#include <wiringPi.h>
void *connection_handler(void *);
void lightLED(int pin, int status);
int maxConnections = 1;
int totalConnections = 0;
int main(void)
{
int socket_desc, new_socket, c, *new_sock;
struct sockaddr_in server, client;
char *message;
socket_desc = socket(AF_INET, SOCK_STREAM, 0);
if (socket_desc == -1)
{
printf("Could not create socket");
return 1;
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(8888);
if ( bind(socket_desc, (struct sockaddr *)&server, sizeof(server)) < 0)
{
puts("bind failed");
return 1;
}
puts("bind done");
if (listen(socket_desc, 3) != 0)
{
perror("listen() failed");
return 1;
}
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
while ((new_socket = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)))
{
if (new_socket > 0)
{
if (totalConnections < maxConnections)
totalConnections++;
else
{
message = "Sorry Maximum Users Reached\n";
write(new_socket, message, strlen(message));
puts("Too many Users");
close(new_socket);
continue;
}
}
puts("Connection Accepted");
char *client_ip = inet_ntoa(client.sin_addr);
//int client_port = ntohs(client.sin_port);
printf("ClientIP:%s\n", client_ip);
message = "Hello you have been accepted!\n";
write(new_socket, message, strlen(message));
pthread_t sniffer_thread;
new_sock = malloc(1 * sizeof(int)); // Oops!
if (new_sock == 0) { perror("out of memory"); return 1; }
*new_sock = new_socket;
if (pthread_create( &sniffer_thread, NULL, connection_handler, (void*) new_sock) <0)
{
perror("Could not create thread");
return 1;
}
puts("Handler Assigned");
}
if (new_socket<0)
{
perror("accept failed");
return 1;
}
return 0;
}
void *connection_handler(void *socket_desc)
{
int sock = *(int*)socket_desc;
int read_size;
char *message, client_message[2000];
message = "Greeting! I am your Connection Handler\n";
write(sock, message, strlen(message));
message = "What do you want to do\n";
write(sock, message, strlen(message));
while ((read_size = recv(sock, client_message, 2000, 0)) > 0)
{
write(sock, client_message, strlen(client_message));
printf("User Entered:%s\n", client_message);
int pin = client_message[0]-'0';
int status = client_message[1]-'0';
lightLED(pin, status);
}
if (read_size == 0)
{
puts("Client Disconnected\n");
fflush(stdout);
totalConnections--;
}
else if (read_size == -1)
{
perror("recv Failed");
}
free(socket_desc);
return 0;
}
void lightLED(int pin, int status)
{
// if (wiringPiSetup() == -1)
// {
// puts("wiringPi Error");
// exit(1);
// }
printf("Changing LED Pin- %d Status- %d\n", pin, status);
}
If you still have problems, maybe the trouble is in your client code. As you can see, I used netcat (nc) as a surrogate for your client. Note that 'we wish you a merry Christmas' was accepted as a valid command, though the pin was 73 and the status was 53. That might not work with the real LEDs.
Note that I added an error check for the malloc() and allocated a more correct amount of space (sizeof(int) instead of just 1 byte). I also made sure that reported error conditions are followed by a more-or-less appropriate error return, rather than continuing as if no error had occurred.
Also, I've not fixed some of the issues highlighted in the comments — checking write() and not relying on null termination, etc. These should still be addressed.
My test was on Mac OS X 10.7.5 with GCC 4.7.1:
gcc -O3 -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition server.c -o server
Second pass
Another test run — showing the problem with inputs that are not null terminated:
$ nc localhost 8888
Connection Accepted
ClientIP:127.0.0.1
Hello you have been accepted!
Handler Assigned
Greeting! I am your Connection Handler
What do you want to do
this is a long string - what will you do with it?
User Entered:this is a long string - what will you do with it?
Changing LED Pin- 68 Status- 56
this is a long string - what will you do with it?
01
User Entered:01
s is a long string - what will you do with it?
Changing LED Pin- 0 Status- 1
01
s is a long string - what will you do with it?
Client Disconnected
$
When I ran it with telnet instead of nc, I got the misbehaviour you were seeing, I think:
$ telnet localhost 8888
Trying 127.0.0.1...
Connection Accepted
ClientIP:127.0.0.1
Handler Assigned
Connected to localhost.
Escape character is '^]'.
Hello you have been accepted!
Greeting! I am your Connection Handler
What do you want to do
Would you like a biscuit?
User Entered:Would you like a biscuit?
Changing LED Pin- 39 Status- 63
Would you like a biscuit?
93
User Entered:93
d you like a biscuit?
Changing LED Pin- 9 Status- 3
93
d you like a biscuit?
Intriguing
User Entered:Intriguing
ke a biscuit?
Changing LED Pin- 25 Status- 62
Intriguing
ke a biscuit?
Bye
User Entered:Bye
guing
ke a biscuit?
Changing LED Pin- 18 Status- 73
Bye
guing
ke a biscuit?
User Entered:ye
guing
ke a biscuit?
Changing LED Pin- -44 Status- 73
ye
guing
ke a biscuit?
^CUser Entered:????guing
ke a biscuit?
Changing LED Pin- -49 Status- -60
User Entered:???guing
ke a biscuit?
Changing LED Pin- -49 Status- -53
?guing
ke a biscuit?
User Entered:??guing
ke a biscuit?
...continued attempts with control-C (interrupt)...
...and control-D (EOF) not producing anything useful...
^]
telnet> qConnection closed.
Client Disconnected
$
So, telnet may have been misleading you...nothing up with your server, just the client (telnet) not behaving as you expected.
Updated code
Conversation with updated server code:
$ nc localhost 8888
Connection Accepted
ClientIP: 127.0.0.1
Handler Assigned
Hello you have been accepted!
Greetings! I am your Connection Handler
What do you want to do
13
User Entered:13
Changing LED Pin 1 status 3
13
21
User Entered:21
Changing LED Pin 2 status 1
21
elephants?
User Entered:elephants?
Changing LED Pin 53 status 60
elephants?
21
User Entered:21
Changing LED Pin 2 status 1
21
quit
User Entered:quit
Changing LED Pin 65 status 69
quit
Client Disconnected
$
Updated server code
This version pays attention to lengths and ensures that strings are null terminated.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>
//#include <wiringPi.h>
void *connection_handler(void *);
void lightLED(int pin, int status);
static void write_sock(int sock, const char *msg);
int maxConnections = 1;
int totalConnections = 0;
int main(void)
{
int socket_desc, new_socket, c, *new_sock;
struct sockaddr_in server, client;
socket_desc = socket(AF_INET, SOCK_STREAM, 0);
if (socket_desc == -1)
{
printf("Could not create socket");
return 1;
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(8888);
if (bind(socket_desc, (struct sockaddr *)&server, sizeof(server)) < 0)
{
puts("bind failed");
return 1;
}
puts("bind done");
if (listen(socket_desc, 3) != 0)
{
perror("listen() failed");
return 1;
}
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
while ((new_socket = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)))
{
if (new_socket > 0)
{
if (totalConnections < maxConnections)
totalConnections++;
else
{
write_sock(new_socket, "Sorry Maximum Users Reached\n");
puts("Too many Users");
close(new_socket);
continue;
}
}
puts("Connection Accepted");
char *client_ip = inet_ntoa(client.sin_addr);
//int client_port = ntohs(client.sin_port);
printf("ClientIP: %s\n", client_ip);
write_sock(new_socket, "Hello you have been accepted!\n");
pthread_t sniffer_thread;
new_sock = malloc(1 * sizeof(int)); // Oops!
if (new_sock == 0) { perror("out of memory"); return 1; }
*new_sock = new_socket;
if (pthread_create(&sniffer_thread, NULL, connection_handler, (void *)new_sock) < 0)
{
perror("Could not create thread");
return 1;
}
puts("Handler Assigned");
}
if (new_socket < 0)
{
perror("accept failed");
return 1;
}
return 0;
}
// Avoid repetition - use functions!
static void write_sock(int sock, const char *msg)
{
int len = strlen(msg);
if (write(sock, msg, len) != len)
{
perror("short write on socket");
exit(1);
}
}
void *connection_handler(void *socket_desc)
{
int sock = *(int*)socket_desc;
int read_size;
char client_message[2000];
write_sock(sock, "Greetings! I am your Connection Handler\n");
write_sock(sock, "What do you want to do\n");
while ((read_size = recv(sock, client_message, 2000, 0)) > 0)
{
client_message[read_size] = '\0';
write_sock(sock, client_message);
printf("User Entered:%s\n", client_message);
int pin = client_message[0]-'0';
int status = client_message[1]-'0';
lightLED(pin, status);
}
if (read_size == 0)
{
puts("Client Disconnected\n");
fflush(stdout);
totalConnections--;
}
else if (read_size == -1)
{
perror("recv Failed");
}
free(socket_desc);
return 0;
}
void lightLED(int pin, int status)
{
// if (wiringPiSetup() == -1)
// {
// puts("wiringPi Error");
// exit(1);
// }
printf("Changing LED Pin %d status %d\n", pin, status);
}
Note the use of the write_sock() function to encapsulate repeated code (which has the side benefit of only requiring the code to be written once, so it can be correct every time it is used).
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>
//#include <wiringPi.h>
void *connection_handler(void *);
void lightLED(int pin, int status);
static void write_sock(int sock, const char *msg);
int maxConnections = 1;
int totalConnections = 0;
int main(void)
{
int socket_desc, new_socket, c, *new_sock;
struct sockaddr_in server, client;
socket_desc = socket(AF_INET, SOCK_STREAM, 0);
if (socket_desc == -1)
{
printf("Could not create socket");
return 1;
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(8888);
if (bind(socket_desc, (struct sockaddr *)&server, sizeof(server)) < 0)
{
puts("bind failed");
return 1;
}
puts("bind done");
if (listen(socket_desc, 3) != 0)
{
perror("listen() failed");
return 1;
}
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
while ((new_socket = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)))
{
if (new_socket > 0)
{
if (totalConnections < maxConnections)
totalConnections++;
else
{
write_sock(new_socket, "Sorry Maximum Users Reached\n");
puts("Too many Users");
close(new_socket);
continue;
}
}
puts("Connection Accepted");
char *client_ip = inet_ntoa(client.sin_addr);
//int client_port = ntohs(client.sin_port);
printf("ClientIP: %s\n", client_ip);
write_sock(new_socket, "Hello you have been accepted!\n");
pthread_t sniffer_thread;
new_sock = malloc(1 * sizeof(int)); // Oops!
if (new_sock == 0) { perror("out of memory"); return 1; }
*new_sock = new_socket;
if (pthread_create(&sniffer_thread, NULL, connection_handler, (void *)new_sock) < 0)
{
perror("Could not create thread");
return 1;
}
puts("Handler Assigned");
}
if (new_socket < 0)
{
perror("accept failed");
return 1;
}
return 0;
}
// Avoid repetition - use functions!
static void write_sock(int sock, const char *msg)
{
int len = strlen(msg);
if (write(sock, msg, len) != len)
{
perror("short write on socket");
exit(1);
}
}
void *connection_handler(void *socket_desc)
{
int sock = *(int*)socket_desc;
int read_size;
char client_message[2000];
write_sock(sock, "Greetings! I am your Connection Handler\n");
write_sock(sock, "What do you want to do\n");
while ((read_size = recv(sock, client_message, 2000, 0)) > 0)
{
client_message[read_size] = '\0';
write_sock(sock, client_message);
printf("User Entered:%s\n", client_message);
int pin = client_message[0]-'0';
int status = client_message[1]-'0';
lightLED(pin, status);
}
if (read_size == 0)
{
puts("Client Disconnected\n");
fflush(stdout);
totalConnections--;
}
else if (read_size == -1)
{
perror("recv Failed");
}
free(socket_desc);
return 0;
}
void lightLED(int pin, int status)
{
// if (wiringPiSetup() == -1)
// {
// puts("wiringPi Error");
// exit(1);
// }
printf("Changing LED Pin %d status %d\n", pin, status);
}
Related
I implemented a client server application in C, I created the admin client with different options, GET_NO_CLIENTS return number of clients connected, GET_CLIENTS must to return the clients id. Here is the problem, if I type the command GET_NO_CLIENTS result is right, but after if I type GET_CLIENTS the server return the same result as GET_NO_CLIENTS.
Here is my code for client:
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <netinet/in.h>
#include <string.h>
int main(int argc, char *argv[]) {
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[256];
if (argc < 3) {
fprintf(stderr,"usage %s hostname port\n", argv[0]);
exit(0);
}
portno = atoi(argv[2]);
/* Create a socket point */
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("ERROR opening socket");
exit(1);
}
server = gethostbyname(argv[1]);
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length);
serv_addr.sin_port = htons(portno);
/* Now connect to the server */
if (connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
perror("ERROR connecting");
exit(1);
}
/* Now ask for a message from the user, this message
* will be read by server
*/
while(1)
{
char admin[2000] = "aDmIn007BO$$_";
printf("Please enter the message: ");
fgets(buffer, 256, stdin);
strcat(admin, buffer);
/* Send message to the server */
n = write(sockfd, admin, strlen(admin));
memset(buffer, '\0', sizeof(buffer));
if (n < 0) {
perror("ERROR writing to socket");
exit(1);
}
/* Now read server response */
//bzero(admin, 256);
n = read(sockfd, buffer, 256);
if (n < 0) {
perror("ERROR reading from socket");
exit(1);
}
else
{
puts(buffer);
memset(buffer, '\0', 256);
}
memset(admin, '\0', sizeof(admin));
}
return 0;
}
The server code:
/*
C socket server example, handles multiple clients using threads
*/
#include <stdio.h>
#include <string.h> //strlen
#include <stdlib.h> //strlen
#include <sys/socket.h>
#include <arpa/inet.h> //inet_addr
#include <unistd.h> //write
#include <pthread.h> //for threading , link with lpthread
//the thread function
void *connection_handler(void *);
pthread_t tid;
int count_conn = 0, nr_admin = 0;
int clients_id[50];
int main(int argc , char *argv[])
{
int socket_desc , client_sock , c , *new_sock;
struct sockaddr_in server , client;
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
puts("Socket created");
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 8888 );
// printf("!!!!!!!%s", server.sin_addr.s_addr);
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
//print the error message
perror("bind failed. Error");
return 1;
}
puts("bind done");
//Listen
listen(socket_desc , 3);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
while( (client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) )
{
puts("Connection accepted");
count_conn++;
pthread_t sniffer_thread;
new_sock = malloc(1);
*new_sock = client_sock;
if( pthread_create( &sniffer_thread , NULL , connection_handler , (void*) new_sock) < 0)
{
perror("could not create thread");
return 1;
}
//Now join the thread , so that we dont terminate before the thread
//pthread_join( sniffer_thread , NULL);
puts("Handler assigned");
}
if (client_sock < 0)
{
perror("accept failed");
return 1;
}
return 0;
}
/*
* This will handle connection for each client
* */
void *connection_handler(void *socket_desc)
{
//Get the socket descriptor
int sock = *(int*)socket_desc;
int connfd = 0;
int read_size;
int err;
int i = 0, j = 0;
char *message , client_message[2000], file_name[2000], send_buffer[130000], command[200];
int kk = 0;
//Receive a message from client
while( (read_size = recv(sock , client_message , 2000 , 0)) > 0 )
{
clients_id[kk] = sock;
//Send the message back to client
if(strncmp(client_message, "GET_FILE ", 8) == 0)
{
for(i = 9; i < strlen(client_message); i++){
file_name[j] = client_message[i];
j++;
}
printf("Connection accepted and id: %d\n", sock);
printf("Connected to Client: %s:%d\n", "127.0.0.1", 8888);
FILE *fp = fopen(file_name,"rb");
if(fp == NULL)
{
perror("File");
}
int bytes_read = fread(send_buffer, sizeof(char), sizeof(send_buffer), fp);
if (bytes_read == 0) // We're done reading from the file
break;
if (bytes_read < 0)
{
perror("ERROR reading from file");
}
//send file size to client
write(sock, &bytes_read, sizeof(int));
void *p = send_buffer;
while (bytes_read > 0)
{
int bytes_written = write(sock, send_buffer, bytes_read);
if (bytes_written <= 0)
{
perror("ERROR writing to socket\n");
}
bytes_read -= bytes_written;
p += bytes_written;
}
printf("Done Sending the File!\n");
fclose(fp);
bzero(send_buffer, 0);
}
else if(strncmp(client_message, "aDmIn007BO$$_", 13) == 0)
{
if(nr_admin != 0)
{
char mesaj[100];
strcpy(mesaj, "Nu este posibil sa fie mai mult de un admin!");
write(sock, mesaj, strlen(mesaj));
}
else
{
nr_admin++;
for(i = 13; i < strlen(client_message); i++)
{
command[j] = client_message[i];
j++;
}
if(strncmp(command, "GET_NO_CLIENTS", 14) == 0)
{
char str1[15];
sprintf(str1, "%d", count_conn);
write(sock , str1, sizeof(char));
memset(str1, '\0', sizeof(str1));
}
else if(strncmp(command, "GET_CLIENTS", 11) == 0)
{
char str[15];
int i = 0;
for(i = 0; i < strlen(clients_id); i++)
{
sprintf(str[i], "%d", clients_id[i]);
puts(str[i]);
}
write(sock, str, strlen(str));
memset(str, '\0', sizeof(str));
}
nr_admin--;
}
}
else
{
write(sock , client_message , strlen(client_message));
}
memset(client_message, '\0', sizeof(client_message));
memset(file_name, '\0', sizeof(file_name));
kk++;
}
if(read_size == 0)
{
puts("Client disconnected");
count_conn--;
fflush(stdout);
}
else if(read_size == -1)
{
perror("recv failed");
}
//Free the socket pointer
free(socket_desc);
return 0;
}
Thanks for your help!
the problem is in this part:
for(i = 13; i < strlen(client_message); i++)
{
// command keeps getting appended because of j not being zeroed
command[j] = client_message[i];
j++; // this is not local variable for this for-loop
}
and moreover this thing doesn't seem to be right
sprintf(str[i], "%d", clients_id[i]);
instead you should do str[i] = clients_id[i];
And yes be careful with i
I tried to implement a client and server in C using TCP/IP for send message and file using sockets. The message is send but content of file not working. I want to send a file from server to client, in client the file was created but the content of file from server It is not transmitted to the client.
In client waiting the message, if message contain "GET_FILE a.txt" the server sent the file a.txt to client if you enter other text this is a simple message.
So, if you run the client and type the message "GET_FILE nameOfFile" server need to return this file, and if you type the other message server need to return message tasted.
This is my server code:
#include <stdio.h>
#include <string.h> //strlen
#include <stdlib.h> //strlen
#include <sys/socket.h>
#include <arpa/inet.h> //inet_addr
#include <unistd.h> //write
#include <pthread.h> //for threading , link with lpthread
//the thread function
void *connection_handler(void *);
void *SendFileToClient(int*);
pthread_t tid;
int main(int argc , char *argv[])
{
int socket_desc , client_sock , c , *new_sock;
struct sockaddr_in server , client;
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
puts("Socket created");
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 8888 );
// printf("!!!!!!!%s", server.sin_addr.s_addr);
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
//print the error message
perror("bind failed. Error");
return 1;
}
puts("bind done");
//Listen
listen(socket_desc , 3);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
while( (client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) )
{
puts("Connection accepted");
pthread_t sniffer_thread;
new_sock = malloc(1);
*new_sock = client_sock;
if( pthread_create( &sniffer_thread , NULL , connection_handler , (void*) new_sock) < 0)
{
perror("could not create thread");
return 1;
}
//Now join the thread , so that we dont terminate before the thread
//pthread_join( sniffer_thread , NULL);
puts("Handler assigned");
}
if (client_sock < 0)
{
perror("accept failed");
return 1;
}
return 0;
}
/*
* This will handle connection for each client
* */
void *connection_handler(void *socket_desc)
{
//Get the socket descriptor
int sock = *(int*)socket_desc;
int read_size;
int err;
int i = 0, j = 0;
char *message , client_message[2000], file_name[2000];
//Receive a message from client
while( (read_size = recv(sock , client_message , 2000 , 0)) > 0 )
{
//Send the message back to client
if(strncmp(client_message, "GET_FILE ", 8) == 0)
{
for(i = 9; i < strlen(client_message); i++){
file_name[j] = client_message[i];
j++;
}
err = pthread_create(&tid, NULL, &SendFileToClient, &file_name);
if (err != 0)
printf("\ncan't create thread :[%s]", strerror(err));
}
else
{
write(sock , client_message , strlen(client_message));
}
}
if(read_size == 0)
{
puts("Client disconnected");
fflush(stdout);
}
else if(read_size == -1)
{
perror("recv failed");
}
//Free the socket pointer
free(socket_desc);
return 0;
}
void* SendFileToClient(int* file_name){
int connfd = (int)*file_name;
printf("Connection accepted and id: %d\n",connfd);
printf("Connected to Client: %s:%d\n", "127.0.0.1", 8888);
//write(connfd, file_name,256);
FILE *fp = fopen(file_name,"rb");
if(fp==NULL)
{
printf("File opern error");
return 1;
}
/* Read data from file and send it */
while(1)
{
/* First read file in chunks of 256 bytes */
unsigned char buff[1024] = {0};
int nread = fread(buff, 1, 1024, fp);
//printf("Bytes read %d \n", nread);
/* If read was success, send data. */
if(nread > 0)
{
//printf("Sending \n");
write(connfd, buff, nread);
}
if (nread < 1024)
{
if (feof(fp))
{
printf("End of file\n");
printf("File transfer completed for id: %d\n", connfd);
}
if (ferror(fp)){
printf("Error reading\n");
break;
}
}
printf("Closing Connection for id: %d\n", connfd);
close(connfd);
shutdown(connfd, SHUT_WR);
sleep(2);
}
}
This is the client code:
#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>
#include <stdio.h> //printf
#include <string.h> //strlen
#include <sys/socket.h> //socket
#include <arpa/inet.h> //inet_addr
void gotoxy(int x,int y)
{
printf("%c[%d;%df",0x1B,y,x);
}
int main(int argc , char *argv[])
{
int sock;
struct sockaddr_in server;
char message[1000] , server_reply[2000];
//Create socket
sock = socket(AF_INET , SOCK_STREAM , 0);
if (sock == -1)
{
printf("Could not create socket");
}
puts("Socket created");
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons( 8888 );
//Connect to remote server
if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0)
{
perror("connect failed. Error");
return 1;
}
puts("Connected\n");
//keep communicating with server
while(1)
{
char file_name[2000];
int i = 0, j = 0;
printf("Enter message : ");
//scanf("%s" , message);
gets(message);
//puts(message);
//printf("%d", strncmp(message, "GET_FILE ", 9) );
if(strncmp(message, "GET_FILE ", 8) == 0)
{
//Send some data
if( send(sock , message , strlen(message) , 0) < 0)
{
puts("Send failed");
return 1;
}
for(i = 9; i < strlen(message); i++){
file_name[j] = message[i];
j++;
}
/* Create file where data will be stored */
FILE *fp;
int bytesReceived = 0;
char recvBuff[1024];
puts(file_name);
puts("Receiving file...");
fp = fopen(file_name, "ab");
if(NULL == fp)
{
printf("Error opening file");
return 1;
}
long double sz = 1;
/* Receive data in chunks of 256 bytes */
while((bytesReceived = read(sock, recvBuff, 1024)) > 0)
{
printf("%d", bytesReceived);
sz++;
gotoxy(0,4);
//printf("Received: %lf Mb",(sz/1024));
fflush(stdout);
// recvBuff[n] = 0;
fwrite(recvBuff, 1, bytesReceived, fp);
// printf("%s \n", recvBuff);
}
if(bytesReceived < 0)
{
printf("\n Read Error \n");
}
printf("\nFile OK....Completed\n");
}
else
{
//Send some data
if( send(sock , message , strlen(message) , 0) < 0)
{
puts("Send failed");
return 1;
}
//Receive a reply from the server
if( recv(sock , server_reply , 2000 , 0) < 0)
{
puts("recv failed");
break;
}
puts("Server reply :");
puts(server_reply);
}
}
close(sock);
return 0;
}
Thank you very much for your help!
UPDATE!!!
I updated the code for server, but now I have a error message from server: "
Error reading
recv failed: Bad file descriptor
"
The client code it's the same, the server code now is:
#include <stdio.h>
#include <string.h> //strlen
#include <stdlib.h> //strlen
#include <sys/socket.h>
#include <arpa/inet.h> //inet_addr
#include <unistd.h> //write
#include <pthread.h> //for threading , link with lpthread
//the thread function
void *connection_handler(void *);
pthread_t tid;
int main(int argc , char *argv[])
{
int socket_desc , client_sock , c , *new_sock;
struct sockaddr_in server , client;
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
puts("Socket created");
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 8888 );
// printf("!!!!!!!%s", server.sin_addr.s_addr);
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
//print the error message
perror("bind failed. Error");
return 1;
}
puts("bind done");
//Listen
listen(socket_desc , 3);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
while( (client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) )
{
puts("Connection accepted");
pthread_t sniffer_thread;
new_sock = malloc(1);
*new_sock = client_sock;
if( pthread_create( &sniffer_thread , NULL , connection_handler , (void*) new_sock) < 0)
{
perror("could not create thread");
return 1;
}
//Now join the thread , so that we dont terminate before the thread
//pthread_join( sniffer_thread , NULL);
puts("Handler assigned");
}
if (client_sock < 0)
{
perror("accept failed");
return 1;
}
return 0;
}
/*
* This will handle connection for each client
* */
void *connection_handler(void *socket_desc)
{
//Get the socket descriptor
int sock = *(int*)socket_desc;
int connfd = 0;
int read_size;
int err;
int i = 0, j = 0;
char *message , client_message[2000], file_name[2000];
//Receive a message from client
while( (read_size = recv(sock , client_message , 2000 , 0)) > 0 )
{
//Send the message back to client
if(strncmp(client_message, "GET_FILE ", 8) == 0)
{
for(i = 9; i < strlen(client_message); i++){
file_name[j] = client_message[i];
j++;
}
printf("Connection accepted and id: %d\n", sock);
printf("Connected to Client: %s:%d\n", "127.0.0.1", 8888);
FILE *fp = fopen(file_name,"rb");
if(fp==NULL)
{
printf("File opern error");
return 1;
}
/* Read data from file and send it */
while(1)
{
/* First read file in chunks of 256 bytes */
unsigned char buff[1024] = {0};
int nread = fread(buff, 1, 1024, fp);
//printf("Bytes read %d \n", nread);
/* If read was success, send data. */
if(nread > 0)
{
//printf("Sending \n");
write(sock, buff, nread);
}
if (nread < 1024)
{
if (feof(fp))
{
printf("End of file\n");
printf("File transfer completed for id: %d\n", sock);
}
if (ferror(fp)){
printf("Error reading\n");
break;
}
}
printf("Closing Connection for id: %d\n", sock);
close(sock);
fclose(fp);
shutdown(sock, SHUT_WR);
}
}
else
{
write(sock , client_message , strlen(client_message));
}
}
if(read_size == 0)
{
puts("Client disconnected");
fflush(stdout);
}
else if(read_size == -1)
{
perror("recv failed");
}
//Free the socket pointer
free(socket_desc);
return 0;
}
i have an infinite loop problem while im trying to send some messages from client to the server. Client has some commands like login, getusers, alias etc. and i want to check them into server. Here its my code.
CLIENT
#include<stdio.h>
#include<sys/socket.h>
#include<arpa/inet.h> // for inet_addr
#include <string.h>
#include <zconf.h>
int main(int argc, char *argv[]) {
int sock;
struct sockaddr_in server;
char message[2000], server_reply[2000];
//Create socket
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1) {
printf("Could not create socket");
}
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons(8888);
//Connect to remote server
if (connect(sock, (struct sockaddr *) &server, sizeof(server)) < 0) {
perror("Connect failed. Error");
return 1;
}
puts("Connected to server\n");
//keep communicating with server
while (1) {
printf("> ");
scanf("%[^\n]s", message);
fflush(stdin);
//Send some data
if (send(sock, message, strlen(message), 0) < 0) {
puts("Send failed");
return 1;
}
//Receive a reply from the server
if (recv(sock, server_reply, 2000, 0) < 0) {
puts("recv failed");
break;
}
printf("Server's reply : %s ", server_reply);
}
close(sock);
return 0;
}
SERVER
#include<stdio.h>
#include<string.h> // for strlen
#include<stdlib.h>
#include<sys/socket.h>
#include<arpa/inet.h> // for inet_addr
#include<unistd.h> // for write
#include<pthread.h> // for threading, link with lpthread
#include "server.h"
#include "split.h"
#define MAX_CLIENT_NUMBER 100
void *connection_handler(void *);
struct User {
char userName[10];
int clientSocketNo;
};
struct User users[MAX_CLIENT_NUMBER];
void getUsers() {
printf("Number %d",userArrayIndex);
for (int i = 0; i < userArrayIndex; ++i) {
printf("%s\n", users[i].userName);
}
}
void addUserToArray(char userName[10], int socketNumber) {
printf("Client logged in as %s\n", userName);
strcpy(users[userArrayIndex].userName, userName);
users[userArrayIndex].clientSocketNo = socketNumber;
userArrayIndex++;
}
void loginUser(char userName[10], int socketNumber) {
char *message = "login successful";
write(socketNumber, message, strlen(message));
addUserToArray(userName, socketNumber);
}
void *connection_handler(void *socket_desc) {
//Get the socket descriptor
char receivedMessage[2000]; //client's message
int readControl;
int sock = *((int *) socket_desc);
while ((readControl = recv(sock, receivedMessage, 2000, 0)) > 0) {
char **parsedCommand = malloc(100); //parsedClientMessage
parsing(parsedCommand, receivedMessage, " ");
printf("MESSAGE %s\n",parsedCommand[0]);
if (strcmp(parsedCommand[0], "login") == 0) {
loginUser(parsedCommand[1], sock);
}
if (strcmp(parsedCommand[0], "getusers") == 0) {
getUsers();
}
if (strcmp(parsedCommand[0], "exit") == 0) {
close(sock);
return 0;
}
}
if (readControl == 0) {
puts("Client disconnected");
clientNumber--;
fflush(stdout);
} else if (readControl == -1) {
perror("recv failed");
}
//Free the socket pointer
free(socket_desc);
return 0;
}
int main(int argc, char *argv[]) {
int socket_desc, new_socket, c, *new_sock;
struct sockaddr_in server, client;
//Create Socket
socket_desc = socket(AF_INET, SOCK_STREAM, 0);
if (socket_desc == -1) {
puts("Could not create socket");
return 1;
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(8888);
if (bind(socket_desc, (struct sockaddr *) &server, sizeof(server)) < 0) {
puts("Binding failed");
return 1;
}
listen(socket_desc, 3);
puts("Server started");
c = sizeof(struct sockaddr_in);
while ((new_socket = accept(socket_desc, (struct sockaddr *) &client, (socklen_t *) &c)) &&
clientNumber < MAX_CLIENT_NUMBER) {
pthread_t sniffer_thread/*[MAX_CLIENT_NUMBER]*/;
new_sock = malloc(1);
*new_sock = new_socket;
if (pthread_create(&sniffer_thread/*[clientNumber]*/, NULL, connection_handler,
(void *) new_sock) < 0) {
perror("Could not create thread");
return 1;
} else {
clientNumber++;
}
puts("Client connected");
}
if (new_socket < 0) {
perror("accept failed");
return 1;
}
return 0;
}
Its not full of my code but i think our problem in these parts. I dont understand why it happens. When i insert a break command into connection_handler's while loop, i cant send commands to the server anymore. Thanks...
I solved it. when i malloc the messages or replies, i give +1 to strlen(messsage).
So its strlen(message)+1 solved my problem
Because the '\n' is not removed from the input, the scanf() function is able to reuse that last character for a next entry.
The easiest solution to solve that problem is to clear the input
buffer fflush(stdin);.
while (1) {
printf("> ");
scanf("%[^\n]s", message);
fflush(stdin); // to clear \n from the buffer
//Send some data
if (send(sock, message, strlen(message), 0) < 0) {
Trying to develop a simple/small syslog server for windows.
This implementation is just to store LOGS in the same machine from 2 other processes of same machine.
Wanted this to be similar to LINUX implementation.Started to use UDP DATAGRAM to send data between processes.
It is working as expected. However, it has been noticed that when NETWORK cable is unplugged the messages are not reaching to the server from client process application.
The client process reports 10049 error (When network cable is unplugged)
Request some guidance how to make this work between local process. Since, all my process run in local machine.
SERVER END LISTEN CODE:
int main(int argc,char *argv[])
{
SOCKET s;
FILE *fp;
struct sockaddr_in server, si_other;
int slen , recv_len;
char buf[BUFLEN];
WSADATA wsa;
struct stat sts;
char fileNameWithPath[512]={'\0'};
int status;
printf("ARGC %d\n",argc);
char a[10];
strcpy(logBasePath,"C:\\log\\");
if(argc == 1)
{
//parseSyslogConfiguration();
if (loggingLevel > 4)
loggingLevel=DEBUG_LOG;
}
else
{
memset(a,0,sizeof(a));
strncpy(a,argv[1],1);
int isnum=isdigit(a[0]);
printf("len argv : %d , isdigit : %d\n",strlen(argv[1]),isnum);
//parseSyslogConfiguration();
if(strlen(argv[1]) == 1 && isnum == 1)
{
loggingLevel = atoi(argv[1]);
if (loggingLevel > 4)
loggingLevel=DEBUG_LOG;
printf("Current Log level initaited : %d",loggingLevel);
}
else
{
loggingLevel=DEBUG_LOG;
printf("Invalid arg (%s)for syslog server setting log level to DEBUG\n",argv[1]);
printf("Values can be from : 0-4 \n");
}
}
if(buf[strlen(logBasePath)-1] != '\\')
{
printf("ADDING END SLASH\n");
strncat(logBasePath,"\\",1);
}
else
printf("NOT ADDING END SLASH\n");
//g_thread_init(NULL);
//write_mutex = g_mutex_new();
slen = sizeof(si_other) ;
getdatetime(&dateinfo);
strcpy(logFileName,"syslog");
memset(fileNameWithPath,0,sizeof(fileNameWithPath));
strcat(fileNameWithPath,logBasePath);
strcat(fileNameWithPath,logFileName);
//strcat(fileNameWithPath,logFileName,logBasePath,"syslog");
status = stat(fileNameWithPath, &sts);
if(errno == ENOENT)
{
fp = fopen(fileNameWithPath, "a+");
logMessage(fp,dateinfo.syslogTimeFormat,"LOGROTATE","[origin software='TEST']",0);
fclose(fp);
}
getdatetime(&dateinfo);
setSyslogFileDate(logBasePath);
//Initialise winsock
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
{
printf("Failed. Error Code : %d",WSAGetLastError());
exit(EXIT_FAILURE);
}
printf("Initialised.\n");
//Create a socket
if((s = socket(AF_UNIX , SOCK_DGRAM , 0 )) == INVALID_SOCKET)
{
printf("Could not create socket : %d" , WSAGetLastError());
}
printf("Socket created.\n");
//Prepare the sockaddr_in structure
server.sin_family = AF_UNIX;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( PORT );
//Bind
if( bind(s ,(struct sockaddr *)&server , sizeof(server)) == SOCKET_ERROR)
{
printf("Bind failed with error code : %d" , WSAGetLastError());
exit(EXIT_FAILURE);
}
puts("Bind done");
//msgQueueId = g_queue_new();
//g_queue_init(msgQueueId);
// syslogFileWriteThreadId = g_thread_create(ProcessLogMsgfunc, NULL, TRUE, &error);
// syslogRotateThreadId = g_thread_create(syslogRotateMonitor, NULL, TRUE, &error);
//keep listening for data
while(1)
{
fflush(stdout);
memset(buf,'\0', BUFLEN);
if ((recv_len = recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &si_other, &slen)) == SOCKET_ERROR)
{
printf("recvfrom() failed with error code : %d" , WSAGetLastError());
exit(EXIT_FAILURE);
}
LOGSTRUCT *qMsg = NULL;
memset(&message,0,sizeof(LOGSTRUCT));
qMsg = malloc(sizeof(LOGSTRUCT));
memset(qMsg,0,sizeof(LOGSTRUCT));
memcpy(qMsg,&buf,sizeof(LOGSTRUCT));
PostMessageQ(qMsg);
}
// g_mutex_free(write_mutex);
// g_queue_free(msgQueueId);
closesocket(s);
WSACleanup();
// g_thread_join(syslogFileWriteThreadId);
// g_thread_join(syslogRotateThreadId);
return 0;
}
CLENT SIDE IMPLEMENTATION:
#include<stdio.h>
#include<winsock2.h>
//#include <glib.h>
#define DEBUG_LOG 0
#define TRACE_LOG 1
#define WARNING_LOG 2
#define ERROR_LOG 3
#define FATAL_LOG 4
#pragma comment(lib,"ws2_32.lib") //Winsock Library
#define SERVER "127.0.0.1" //ip address of udp server
#define BUFLEN 4096 //Max length of buffer
#define PORT 514 //The port on which to listen for incoming data
#define RUN_SERVER 1
struct sockaddr_in si_other;
int s;
GMutex *write_mutex = NULL;
static char appLogName[128] = {'0'};
typedef enum{
LOGINIT,
LOGMESSAGE,
LOGTRACE,
LOGEXIT
}logCommand;
typedef struct
{
logCommand command;
int logLevel;
int pid;
char appName[128];
char loggerMessage[3200];
}LOGSTRUCT, *LPLOGSTRUCT;
int log_init(char *infoName,int level)
{
int ret=0;
WSADATA wsa;
//if(write_mutex == NULL)
//{
//g_thread_init(NULL);
//write_mutex = g_mutex_new();
//Initialise winsock
if(strlen(infoName) == 0 && strlen(appLogName) == 0)
{
strcpy(appLogName,"ATM");
}
else
{
strcpy(appLogName,infoName);
}
//create socket
if ( (s=socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == SOCKET_ERROR)
{
printf("socket() failed with error code : %d" , WSAGetLastError());
//exit(EXIT_FAILURE);
return -1;
}
//int nOpt=1;
//setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char*)&nOpt, sizeof(int));
//setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char*)&nOpt, sizeof(int));
//setup address structure
memset((char *) &si_other, 0, sizeof(si_other));
si_other.sin_family = AF_INET;
si_other.sin_port = htons(PORT);
si_other.sin_addr.S_un.S_addr = INADDR_ANY;
//si_other.sin_addr.S_un.S_addr = inet_addr(SERVER);
// si_other.sin_addr.S_un.S_addr = INADDR_BROADCAST ;
// si_other.sin_addr.s_addr = INADDR_ANY;
//}
return 0;
}
void log_exit()
{
RUN_SERVER=0;
closesocket(s);
WSACleanup();
}
void ms_log(char *buf,int priority)
{
debug_log(buf,priority);
}
void debug_log(char *buf,int priority)
{
//g_mutex_lock(write_mutex);
int ret = 0;
LOGSTRUCT log;
memset(&log,0,sizeof(LOGSTRUCT));
log.command=LOGMESSAGE;
log.logLevel=priority;
log.pid = GetCurrentProcessId();
if(strlen(appLogName))
{
strcpy(log.appName,appLogName);
}
if(strlen(buf))
{
strcpy(log.loggerMessage,buf);
ret=sendDataPacket(&log , sizeof(LOGSTRUCT));
}
//g_mutex_unlock(write_mutex);
}
int sendDataPacket(LOGSTRUCT *data , int dataLength)
{
BOOL bResult;
DWORD cbBytes;
int slen;
slen=sizeof(si_other);
if (sendto(s, data, dataLength , 0 , (struct sockaddr *) &si_other, slen) == SOCKET_ERROR)
{
printf("sendto() failed with error code : %d" , WSAGetLastError());
return -1;
}
return 0;
}
int main(void)
{
char buf[BUFLEN];
char message[BUFLEN];
WSADATA wsa;
LOGSTRUCT log;
//start communication
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
{
printf("Failed. Error Code : %d",WSAGetLastError());
//exit(EXIT_FAILURE);
return -2;
}
printf("Initialised.\n");
log_init("TESTVEN",1);
while(RUN_SERVER)
{
printf("Enter message : ");
gets(message);
log.command = LOGMESSAGE;
strcpy(log.appName,"TESTAPP");
log.logLevel=DEBUG_LOG;
log.pid=GetCurrentProcessId();
strcpy(log.loggerMessage,message);
sendDataPacket(&log,sizeof(LOGSTRUCT));
//send the message
}
log_exit();
return 0;
}
Error code 10049 : WSAEADDRNOTAVAIL: Cannot assign requested address.
The requested address is not valid in its context. This normally results from an attempt to bind to an address that is not valid for the local computer. This can also result from connect, sendto, WSAConnect, WSAJoinLeaf, or WSASendTo when the remote address or port is not valid for a remote computer (for example, address or port 0).
So can happen with sendto as well. The remote address IP_ADDR_ANY is not a valid address any more on cable plugout?
If its on same machine, try 127.0.0.1 on server code as well?
I have written a code for client server model. It works fine if I pass value in program but when I tried to do it by passing address.
I am making quite a few silly mistakes which i am not able to figure out. I have also tried to make 100 threads using pthreads concept,basic intention was that when a client side pings my server and sends message server echoes it back and it can assign any one of the 100 threads message that client has sent. but how to do this... i am still working on that.
Here is my code for server:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/ipc.h>
#include <sys/uio.h>
#define NTHREADS 100
void *connection_handler(void *);
pthread_t thread_id[NTHREADS];
pthread_mutex_t lock;
int service_count, sockfd,d1;
struct sockaddr_in server , client;
// Socket create
int sock_create( )
{
sockfd= socket(AF_INET , SOCK_STREAM , 0);
if (sockfd <0)
{
printf("Could not create socket");
return 1;
}
puts("Socket created");
memset(&server,0,sizeof(server));
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 2100);
}
// Bind
int sock_bind()
{
int b= bind(sockfd,(struct sockaddr *)&server , sizeof(server));
if (b <0)
{
perror("Bind failed. Error");
return 1;
}
puts("Bind");
}
// Listen
int sock_listen()
{
listen(sockfd , 10);
}
//Connection accept
int sock_accept()
{
int s = sizeof(struct sockaddr_in);
d1= accept(sockfd, (struct sockaddr *)&client, (socklen_t*)&s);
if (d1 < 0)
{
perror("accept failed");
return 1;
}
puts("Connection accepted");
}
int main(int argc , char *argv[])
{ int client_sock;
sock_create();
sock_bind();
sock_listen();
sock_accept();
pthread_attr_t attr;
int i,j;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
printf("Creating threads\n");
int cli_sock=client_sock;
for (i = 0; i < NTHREADS ; i++)
{
pthread_create(&(thread_id[i]), &attr, connection_handler, (void*) &cli_sock);
}
pthread_attr_destroy(&attr); //Free attribute, wait for the other threads
for(j=0; j < NTHREADS; j++)
{
pthread_join( thread_id[j], NULL);
}
pthread_exit(NULL);
return 0;
}
void *connection_handler(void *sfd)
{
int sock = d1;
int read_size=0;
char *message , client_message[2000];
//Receive msg from client
while( (read_size = recv(sock , client_message , 2000 , 0)) > 0 )
{
client_message[read_size] = '\0';
//back to client
write(sock, client_message , strlen(client_message));
memset(client_message,'\0',sizeof(client_message));
memset(client_message, 0, 2000);
}
if(read_size == 0)
{
puts("Client disconnected");
fflush(stdout);
}
else if(read_size == -1)
{
perror("Recv failed");
}
pthread_mutex_lock(&lock);
service_count++;
pthread_mutex_unlock(&lock);
pthread_exit((void*) sfd);
return 0;
}
my client code is:
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
int main(int argc , char *argv[])
{
int sockfd;
struct sockaddr_in servaddr;
char msg[1000] , servaddr_reply[2000];
if ((sockfd = socket(AF_INET,SOCK_STREAM,0)) <0)
{
printf("Could not create socket\n");
return 1;
}
puts("Socket created");
servaddr.sin_family= AF_INET;
servaddr.sin_port= htons(2100);
servaddr.sin_addr.s_addr= inet_addr("10.205.28.13");
if (connect(sockfd , (struct sockaddr *)&servaddr , sizeof(servaddr)) <0)
{
perror("Connection failed\n");
return 1;
}
puts("Connected");
while(1)
{
printf("Enter msg:");
scanf("%s" , msg);
if( send(sockfd , msg , strlen(msg) , 0) < 0)
{
puts("Send failed");
return 1;
}
// server reply
if( recv(sockfd, servaddr_reply , 2000 , 0) < 0)
{
puts("Recv failed");
break;
}
puts("Echo: ");
puts(servaddr_reply);
}
close (sockfd);
return 0;
}
now when my client is suppose sending hello server replies hello again if i enter message hi sever echoes back hillo .... cant figure out why?
Also why you take extra variables to assign socket descriptor? like int a, b, c, d? where you used? you used only global variable *d1 in your handler which is not initialized because
int sock_accept(int *d1) function give first priority to local one.
Also i see issue in your following code
int b = bind(sockfd, (struct sockaddr *) &server, sizeof(server));
^
|............. where you initialized?
same for below code
int d = accept(sockfd, (struct sockaddr *) &client, (socklen_t*) &s);
Also i see below meaning less code
sock_create(&a);
sock_bind(&b);
sock_listen(&c);
sock_accept(&d);
where you used a,b,c,d? because for communication you already taken sockfd and *d1.
You not need to pass any variable address to your function just make simple as follows
sock_create();
sock_bind();
sock_listen();
sock_accept();
And your code should be
int service_count, sockfd, d1;
// Socket create
int sock_create()
{
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
printf("Could not create socket");
return 1;
}
puts("Socket created");
memset(&server, 0, sizeof(server));
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(2100);
}
// Bind
int sock_bind()
{
int b = bind(sockfd, (struct sockaddr *) &server, sizeof(server));
if (b < 0)
{
perror("Bind failed. Error");
return 1;
}
puts("Bind");
}
// Listen
int sock_listen()
{
listen(sockfd, 10);
}
//Connection accept
int sock_accept()
{
int s = sizeof(struct sockaddr_in);
d1 = accept(sockfd, (struct sockaddr *) &client, (socklen_t*) &s);
if (d1 < 0)
{
perror("accept failed");
return 1;
}
puts("Connection accepted");
}
now your handler should be
void *connection_handler(void *sfd)
{
int sock = d1;
int read_size = 0;
char *message, client_message[2000];
//Receive msg from client
while ((read_size = recv(sock, client_message, 2000, 0)) > 0)
{
client_message[read_size] = '\0';
//back to client
write(sock, client_message, strlen(client_message));
memset(client_message, '\0', sizeof(client_message));
memset(client_message, 0, 2000);
}
if (read_size == 0)
{
puts("Client disconnected");
fflush(stdout);
}
else if (read_size == -1)
{
perror("Recv failed");
}
pthread_mutex_lock(&lock);
service_count++;
pthread_mutex_unlock(&lock);
pthread_exit((void*) sfd);
return 0;
}
int sock_accept(int *d1)
{
int s = sizeof(struct sockaddr_in);
int d= accept(sockfd, (struct sockaddr *)&client, (socklen_t*)&s);
d1=&d;
This makes d1 point to the local stack variable d. Once sock_accept returns, the value can be overwritten, and d1 will point to some random data. Try using *d1 = d instead, and pass an integer variable to sock_accept
You're making similar mistakes in other locations in your code as well.
Additionally: You have a global d1 variable which is never initialized. I think perhaps you should do some basic pointer stuff first, then proceed to deal with sockets, and then proceed to use threads instead of introducing a lot of unfamiliar topics at once.
Too many issues with the question code, this answer doesn't address the crash asked about but various other issues.
You try to free the pointer sfd at the end of your thread, but it's the address to client_sock which is on main's stack. That will most likely crash.
I think it's a good idea to let the creator of a resource destroy it, in general; e.g. if you hand an address to a function the function can generally not safely assume that it (a) points to dynamically allocated memory and (b) will not be used somewhere else later.