Jump to content


Check out our Community Blogs

Register and join over 40,000 other developers!


Recent Status Updates

View All Updates

Photo
- - - - -

Terminal and remote connections

c unix connection

This topic has been archived. This means that you cannot reply to this topic.
3 replies to this topic

#1 MaxBummer

MaxBummer

    CC Newcomer

  • Member
  • PipPip
  • 21 posts

Posted 15 January 2013 - 12:58 PM

I have the following requirements, to create a client application to connect to the program, send commands to it and receive the output through the network socket used for the connection.
I was given an example of how it should work :
client 123.123.123.123 5050
(client connects to server running at IP 123.123.123.123, port 5050)
$ Client connected, please enter command to send:
ls -l | grep -e 'something'
$ Server returned:
...
Here are the client respectively the server codes. How can I make the server to supporting any number of client connections, (multi-threaded server as far as I know)? Appreciate any code suggestions or other specifications, thank you.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <pthread.h>

void error(const char *msg) {
perror(msg);
exit(0);
}

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]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
	 error("ERROR opening socket");

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);
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
	 error("ERROR connecting");


bzero(buffer,256);
int doExit = 1;

while(doExit) {
printf("Enter message:");
fgets(buffer, 255, stdin);

buffer[strlen(buffer)-1] = '\0';
doExit = strcmp(buffer, "exit");
n = strlen(buffer);
write(sockfd, &n, sizeof(int));
write(sockfd, buffer, n);
read(sockfd, &n, sizeof(int));
read(sockfd, buffer, n);
buffer[n] = '\0';
printf("Response: %s\n", buffer);
}
// n = read(sockfd,buffer,255);
if (n < 0)
		 error("ERROR reading from socket");

printf("%s\n",buffer);
close(sockfd);
return 0;
}

And the server,
/* A simple server in the internet domain using TCP
The port number is passed as an argument */
#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 <pthread.h>

	 int sockfd, newsockfd[11], portno;
	 socklen_t clilen;
	 char buffer[2560];
	 struct sockaddr_in serv_addr, cli_addr;
	 int n;


void error(const char *msg) {
perror(msg);
exit(1);
}

void execution(char *command) {
//command[strlen(command)-1] = '\0';
//printf(">");
char **arguments;
char *cuv;
int k = 0;
arguments = (char**)malloc(sizeof(char)*50);
cuv = strtok(command, " ");
arguments[k] = malloc(strlen(cuv)*sizeof(char));
if(arguments[k] != NULL) {
strcpy(arguments[k],cuv);
k++;
}

while(cuv) {
cuv = strtok(NULL," ");
		 if(cuv == NULL)
			 arguments[k] = NULL;
else
arguments[k] = malloc(strlen(cuv)*sizeof(char));

if(arguments[k] != NULL) {
strcpy(arguments[k],cuv);
k++;
}
}

//int n = fork();
//if(n==0) {
execvp(arguments[0],arguments);
//}
//printf(">");
}

void *start(void *arg) {
int i = *((int*)arg);
	 newsockfd[i] = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
	 if (newsockfd[i] < 0)
		 error("ERROR on accept");

	 bzero(buffer,2560);
int doExit = 1;
int fd[2];
int status;


	 while(doExit) {
if(pipe(fd)<0) {
	 printf("Eroare la crearea pipe-ului\n");
	 exit(1);
	 }
//n = read(newsockfd[i],buffer,255);
read(newsockfd[i], &n, sizeof(int));
read(newsockfd[i], buffer, n);
buffer[n] = '\0';
doExit = strcmp(buffer, "exit");
int pid=fork();


if(pid==0){
close(fd[0]);
dup2(fd[1],1);
//close(fd[1]);
//execlp("dir","dir",NULL);
execution(buffer);


}
// printf("Received: %s\n", buffer);
/*strcpy(buffer, "I got it!");
n = strlen(buffer);
write(newsockfd[i], &n, sizeof(int));
write(newsockfd[i], buffer, n);*/

else{
//wait(&status);
close(fd[1]);
wait(&status);
while((n=read(fd[0],buffer,2559))>0){
buffer[n] = '\0';
// printf("%s",buffer);
write(newsockfd[i], &n, sizeof(int));
write(newsockfd[i], buffer, n);
}
close(fd[0]);
}
//printf("Received: %s\n", buffer);
//strcpy(buffer, "I got it!");
//n = strlen(buffer);
//write(newsockfd[i], &n, sizeof(int));
//write(newsockfd[i], buffer, n);

	 }

	 close(newsockfd[i]);




}

int main(int argc, char *argv[]) {
pthread_t threads[10];

	 if (argc < 2) {
		 fprintf(stderr,"ERROR, no port provided\n");
		 exit(1);
	 }

	 sockfd = socket(AF_INET, SOCK_STREAM, 0);

	 if (sockfd < 0)
	 error("ERROR opening socket");




	 bzero((char *) &serv_addr, sizeof(serv_addr));
	 portno = atoi(argv[1]);
	 serv_addr.sin_family = AF_INET;
	 serv_addr.sin_addr.s_addr = INADDR_ANY;
	 serv_addr.sin_port = htons(portno);


if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
			 error("ERROR on binding");
	 listen(sockfd,5);
	 clilen = sizeof(cli_addr);
int i, *p;
for(i = 0; i < 10; i++) {
p = (int*)malloc(sizeof(int));
*p = i;
pthread_create(&threads[i], NULL, start, p);
}
for(i = 0; i < 10; i++)
pthread_join(threads[i], NULL);

	 close(sockfd);
	 return 0;
}



#2 Flying Dutchman

Flying Dutchman

    CC Leader

  • Expert Member
  • PipPipPipPipPipPipPip
  • 1090 posts

Posted 15 January 2013 - 02:42 PM

I'd say linked list (that stores socket descriptors) would be the best.

The roots of education are bitter, but the fruit is sweet.


#3 BlackRabbit

BlackRabbit

    CodeCall Legend

  • Expert Member
  • PipPipPipPipPipPipPipPip
  • 3871 posts

Posted 15 January 2013 - 03:15 PM

OK, let's go step by step, first my questions:

1. for the record: platform, compiler, etc
2. code of pthread.h ( I assume it creates if not exist )
3. what is what the program needs

Since the server has no visible variable about threads, i guess it's all on pthread, we will work on that

#4 0xDEADBEEF

0xDEADBEEF

    CC Devotee

  • Senior Member
  • PipPipPipPipPipPip
  • 790 posts

Posted 18 January 2013 - 04:49 AM

Either using fork on unix.
a store of fd's, and non-blocking io
or a store of fd's and io multiplexing.

Creating SEGFAULTs since 1995.





Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download