So i'm trying to make multiple clients logon to a server through filesockets, and perform simple commands like ls -l, ls, mkdir.
I've managed to make one client recieve output of ls -l command, sometimes, its buggy.
Now i've been sitting for days trying to figure out how to fork() correctly to handle multiple clients, and what sockets to use, close and so on. Perhaps someone can shed some light?
To make it work the client program must be in the same directory as the server program (did not know how to make a path from different folder of client program to the socket).
Client:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#define SOCK_PATH "socket"
int main(void)
{
int s, t, len,i=0;
struct sockaddr_un remote;
char str[10000];
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
printf("Trying to connect...\n");
remote.sun_family = AF_UNIX;
strcpy(remote.sun_path, SOCK_PATH);
len = strlen(remote.sun_path) + sizeof(remote.sun_family);
if (connect(s, (struct sockaddr *)&remote, len) == -1) {
perror("connect");
exit(1);
}
printf("Connected.\n");
while(printf("> "), fgets(str, 10000, stdin), !feof(stdin)) {
if (send(s, str, strlen(str), 0) == -1) {
perror("send");
exit(1);
}
if ((t=recv(s, str, 10000, 0)) > 0) {
str[t] = '\0';
printf("echo> %s", str);
for(i=0;i<9999;i++)
str[i]=NULL;
} else {
if (t < 0) perror("recv");
else printf("Connection with server terminated.\n");
exit(1);
}
}
close(s);
return 0;
}
Server:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#define SOCK_PATH "socket"
int main( int argc, char *argv[] )
{
int s, s2, t, len;
struct sockaddr_un local, remote;
char str[1000];
char* arg_list[2220];
char str1[1000], str2[1000];
int z=0;
for(z=0;z<99;z++){
str1[z] = NULL;
str2[z] = NULL;
}
for(;;){
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
local.sun_family = AF_UNIX;
strcpy(local.sun_path, SOCK_PATH);
unlink(local.sun_path);
len = strlen(local.sun_path) + sizeof(local.sun_family);
if (bind(s, (struct sockaddr *)&local, len) == -1) {
perror("bind");
exit(1);
}
if (listen(s, 5) == -1) {
perror("listen");
exit(1);
}
printf("Waiting for connections\n");
t = sizeof(remote);
if ((s2 = accept(s, (struct sockaddr *)&remote, &t)) == -1) { //Server waits for client to connect
perror("accept");
exit(1);
}
pid_t childPID;
childPID = fork();
if(childPID >= 0) // Fork was successful
{
if(childPID == 0) // Child process
{
printf("\I am child\n");
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
local.sun_family = AF_UNIX;
strcpy(local.sun_path, SOCK_PATH);
unlink(local.sun_path);
len = strlen(local.sun_path) + sizeof(local.sun_family);
if (bind(s, (struct sockaddr *)&local, len) == -1) {
perror("bind");
exit(1);
}
if (listen(s, 5) == -1) {
perror("listen");
exit(1);
}
printf("Connected.\n");
int active = 0;
int done = 0;
int sent = 0;
do{
int n = recv(s2, str, 1000, 0);
if(n <= 0) {
if (n < 0) perror("recv");
done = 1;
}
active = 1;
str[strcspn ( str, "\n" )] = '\0'; // String stuff below ***
strcpy(str1,str);
int i=0,k=0;
while (str1[i] != ' ')
i++;
while (str1[i] != '\0'){
str2[k] = str1[i+1];
k++;
i++;
}
i=0;
while (str1[i] != ' ')
i++;
str1[i] = '\0'; // String stuff above ***
int spawn (char* program, char** arg_list) // Executing the clients command
{
/* printf("\n\nprogram = %s\narg_list = %s\n\str1=%s!!!\nstr2=%s\n\n",program,arg_list,str1,str2);*/
dup2(s2, STDOUT_FILENO); //Redericting information to socket
dup2(s2, STDERR_FILENO);
execvp (program, arg_list);abort (); // Executing the clients command
}
char command[2222];
char * tmp;
i=0;
tmp = strtok (command," ");
arg_list[0] = tmp;
while (tmp != NULL)
{
tmp = strtok (NULL, " ");
arg_list[i+1] = tmp;
i++;
}
char* arg1[] = {
str1,
NULL
};
char* arg2[] = {
str1,
str2,
NULL
};
if (!done && sent == 0 && active == 1){
if(str2[0] >= '+' && str2[0] <= 'DEL'){ /* Ugly solution to make commands work.. .sometimes.*/
if(str2[1] >= '+' && str2[1] <= 'DEL')
spawn (str1, arg2);}
else
spawn (str1, arg1);
}
sent = 0;
for(z=0;z<99;z++){
str1[z] = NULL;
str2[z] = NULL;
}
}while (!done);
//close(s2); // Don't know where to close the sockets
}
else //Parent process
{
printf("\nI'll just get back to my listening state - the (;;) loop \n");
//close(s2);
}
}
else // Fork failed
{
printf("\nFork failed, quitting!\n");
return 1;
}
}
return 0;
}