Advertisement

[x]
Attachment Details

[C] ASCII Server

[x]
The Solution Rating System

With so many solutions, how can you tell which solutions are most likely to help you and which ones are not? To provide you with a tool to use, we rate our solutions based on various elements that most accurately determine if a solution is a quality solution. To explain what factors affect the solution rating, here are the elements we take into consideration when formulating our solution rating.

  • The Grade of the Solution
  • The Zone Rank of the Expert Providing the Solution
  • The Number of Author and Expert Comments
  • The Number of Experts Contributing
  • The Feedback of the Community

Your Input Matters
Because of the way the system is set up, the most important variable in this equation is you. As a member of Experts Exchange, you are able to cast your vote on the quality of the solutions in regard to how complete, accurate, helpful and easy to understand each solution is. When you provide your feedback, each rating is adjusted accordingly. So, if you see a solution that has a poor rating that you think is a good solution, let us know by rating it. As you do, the rating will be adjusted and will become more accurate for other members of our site.

If you have any suggestions that you would like to make for our rating system, please ask a question in the Suggestions Zone of Community Support.

Thank you!

9.8
Referring to my previous Q: http://www.experts-exchange.com/Programming/Languages/C/Q_23505779.html?cid=239#a21894284

I'd like to ask you if there is a possibility to change my actual code in order to use ASCII code for each char which it receives and sends.

As i read somewhere on the net, to do this i need to use sscanf() to read from client and snprintf() to write in the buffer...
but what's the best method to do this?

One of my friend show me the result of is server with another client, it was something like this:

(./client) trace - expect_bytes:
(./client) - expected 'WHO?'
(./client) - received 'WHO?'
(./client) trace - send_bytes(HELOGianni Pautasso\r\n)
(./client) trace - expect_bytes:
(./client) - expected 'PASS'
(./client) - received 'PASS'
(./client) trace - send_bytes(bogianen\r\n)
(./client) trace - expect_bytes:
(./client) - expected 'GOOD'
(./client) - received 'GOOD'
(./client) trace - send_bytes(LIST)
(./client) trace - expect_bytes:
(./client) - expected 'HERECD\r\nDVD\r\nUSB4GB\r\n\r\n'
(./client) - received 'HERECD\r\nDVD\r\nUSB4GB\r\n\r\n'
(./client) trace - convert_escape:
(./client) - original 'FIND\s2\s0'
(./client) trace - send_bytes(FIND\000\002\000\000)
(./client) trace - convert_escape:
(./client) - original 'HERE\s2\s25'
(./client) error - expect_bytes:
(./client) - expected 'HERE\000\002\000\031'
(./client) - received 'HERE\000\002\000\000'
(./client) info - test 'basic_tests_read' failed

it looks like the client sends and want to receive ASCII code for each char...
I sended my server to my friend and this was the result:

my SERVER:

(./clientt) trace - expect_bytes:
(./client) - expected 'WHO?'
(./client) - received 'WHO?'
(./client) trace - send_bytes(HELOGianni Pautasso\r\n)
(./client) error - timed out (15 s) expecting bytes:
(./client) - expected 'PASS'
(./client) info - test 'basic_tests_read' failed

may be it's because my server doesn't check if username ends with \r\n ?
or what else?

In order to use ASCII code, i have to call sscanf each time i call Readn() in my server code? and then to store what i read in a string... and then if i want to send it back to the client, i have to copy it with snprintf()?

Or my server is already fine and it didn't work just because it isn't able to handle the username which ends with \r\n ?

Thanks for all!
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307:
308:
309:
310:
311:
312:
313:
314:
315:
316:
317:
318:
319:
320:
321:
322:
323:
324:
325:
326:
327:
328:
329:
330:
331:
332:
333:
334:
335:
336:
337:
338:
339:
340:
341:
342:
343:
344:
345:
346:
347:
348:
349:
350:
351:
352:
353:
354:
355:
356:
357:
358:
359:
360:
361:
362:
363:
364:
365:
366:
367:
368:
369:
370:
371:
372:
373:
374:
375:
376:
377:
378:
379:
380:
381:
382:
383:
384:
385:
386:
387:
388:
389:
390:
391:
392:
393:
394:
395:
396:
397:
398:
399:
400:
401:
402:
403:
404:
405:
406:
407:
408:
409:
410:
411:
412:
413:
414:
415:
416:
417:
418:
419:
420:
421:
422:
423:
424:
425:
426:
427:
428:
429:
430:
431:
432:
433:
434:
435:
436:
437:
438:
439:
440:
441:
442:
443:
444:
445:
446:
447:
448:
449:
450:
451:
452:
453:
454:
455:
456:
457:
458:
459:
460:
461:
462:
463:
464:
465:
466:
467:
468:
469:
470:
471:
472:
473:
474:
475:
476:
477:
478:
479:
480:
481:
482:
483:
484:
485:
486:
487:
488:
489:
490:
491:
492:
493:
494:
495:
496:
497:
498:
499:
500:
501:
502:
503:
504:
505:
506:
507:
508:
509:
510:
511:
512:
513:
514:
515:
516:
517:
518:
519:
520:
521:
522:
523:
524:
525:
526:
527:
528:
529:
530:
531:
532:
533:
534:
535:
536:
537:
538:
539:
540:
541:
542:
543:
544:
545:
546:
547:
548:
549:
550:
551:
552:
553:
554:
555:
556:
557:
558:
559:
560:
561:
562:
563:
564:
565:
566:
567:
568:
569:
570:
571:
572:
573:
574:
575:
576:
577:
578:
579:
580:
581:
582:
583:
584:
585:
586:
587:
588:
589:
590:
591:
592:
593:
594:
595:
596:
597:
598:
599:
600:
601:
602:
603:
604:
605:
606:
607:
608:
609:
610:
611:
612:
613:
614:
615:
616:
617:
618:
619:
620:
621:
622:
623:
624:
625:
626:
627:
628:
629:
630:
631:
632:
633:
634:
635:
636:
637:
638:
639:
640:
641:
642:
643:
644:
645:
646:
647:
648:
649:
650:
651:
652:
653:
654:
655:
656:
657:
658:
659:
660:
661:
662:
663:
664:
665:
666:
667:
668:
669:
670:
671:
672:
673:
674:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <arpa/inet.h>       
#include <unistd.h>           
#include <ctype.h>
#include <sys/wait.h>
#include "sockwrap.h"
#include "errlib.h"
#if 0
#include "sockwrap_hex.gh" // in order to do debug
#endif
 
/***********************************************************************************************
**                       List of Defines used for the messages                               **
***********************************************************************************************/
 
#define MAX_LINE 1000 /* mainly for array size */
#define HERE "HERE"
#define WHO "WHO?"
#define NOOB "NOOB"
#define PASS "PASS"
#define BYE "BYE!"
#define FAIL "FAIL"
#define NAUT "NAUT"
#define FULL "FULL"
#define GOOD "GOOD"
#define ALERT "ALERT"
#define WHAT "????"
 
/***********************************************************************************************
**                       Linked List Struct                                                  **
***********************************************************************************************/
 
struct NODE {
	int code; 
	char name[1000];
	struct NODE *next;
	int size;
	int line;
};
 
 
/***********************************************************************************************
**                      Global Variables                                                     **
***********************************************************************************************/
 
struct NODE *llist;
 
int size = 0;
int auth = 0;
int linea = 0;
char *prog;
 
 
/***********************************************************************************************
**                       Function prototypes                                                  **
***********************************************************************************************/
 
int  search_value(struct NODE *llist, int text_line, int fd);
void append_node(struct NODE *llist, char* name, int num, int linea);
void display_list(struct NODE *llist, int fd);
int verify_login(char *, char *);
void clean_list(struct NODE *llist);
void listen_client_requests(int fd);
void load_file_in_list(int fd);
 
 
/***********************************************************************************************
**                       Strings which server sends                                           **
***********************************************************************************************/
 
void sendHERE(int fd){
	Writen(fd, HERE, strlen(HERE));
}
 
void sendWHO(int fd){
	Writen(fd, WHO, strlen(WHO));
}
 
void sendNOOB(int fd){
	Writen(fd, NOOB, strlen(NOOB));
}
 
void sendPASS(int fd){
	Writen(fd, PASS, strlen(PASS));
}
 
void sendFAIL(int fd){
	Writen(fd, FAIL, strlen(FAIL));
}
 
void sendGOOD(int fd){
	Writen(fd, GOOD, strlen(GOOD));
}
 
void sendNAUT(int fd){
	Writen(fd, NAUT, strlen(NAUT));
}
 
void sendALERT(int fd){
	Writen(fd, ALERT, strlen(ALERT));
}
 
void sendFULL(int fd){
	Writen(fd, FULL, strlen(FULL));
}
 
void sendBYE(int fd){
	Writen(fd, BYE, strlen(BYE));
}
 
void sendWHAT(int fd){
	Writen(fd, WHAT, strlen(WHAT));
}
 
/***********************************************************************************************
**                    In order to display the list when server receives LIST                  **
***********************************************************************************************/
 
void display_list(struct NODE *llist, int fd)
{
	
	char stringa[MAX_LINE];
	
	if (llist->next == NULL )
		sendNOOB(fd);  
	
	if(llist->next != NULL)
	{
		
		sendHERE(fd);
		int i;
		
		for(i=0; i < (size-1); i++)
		{
			
			llist = llist->next;
			snprintf(stringa, sizeof(stringa), "%s\r\n", llist->name);
			Writen(fd, stringa, strlen(stringa));
			
		}
		
		llist = llist->next;
		snprintf(stringa, sizeof(stringa), "%s\r\n\r\n", llist->name);
		Writen(fd, stringa, strlen(stringa));
		
	}  
	
	
}
 
/***********************************************************************************************
**                  I store the content of text file in my Linked List                        **
***********************************************************************************************/
 
void append_node(struct NODE *llist, char * name, int num, int line)
{
	
	while(llist->next != NULL) 
	llist = llist->next; 
	llist->next = (struct NODE *)malloc(sizeof(struct NODE));
	llist->next->code = num;
	llist->next->line = line;
	strcpy((char*)llist->next->name, (char*)name);
	llist->next->next = NULL;
	
}
 
 
/***********************************************************************************************
**                  Search for Values present at a given text line                           **
***********************************************************************************************/
 
int search_value(struct NODE *llist, int text_line, int fd)
{
		
	
	while(llist != NULL)
	{
		
		if(llist->line == text_line)
		{ 			
			
			return llist->code;
			break;		                	
		}	 
		 
		llist = llist->next;
		
	}
	
	return 65535;
	
}
 
 
/***********************************************************************************************
**                                 Free all the list                                          **
***********************************************************************************************/
 
void clean_list(struct NODE *llist)
{
		
	
	while(llist != NULL)
	{	
		
		struct NODE *tmp = llist->next;
            free(llist);
            llist = tmp;
		
	}
	
	
}
 
 
/***********************************************************************************************
**                                  Children Handling                                         **
***********************************************************************************************/
 
int count = 0; 
 
void signal_handler(int sig)
{
	pid_t pid;
	int status;
	
	/* for solaris and unix system */
	signal(sig, signal_handler);
	
	while( (pid = waitpid(-1,&status,WNOHANG)) > 0)
	{		    
		count--; /* child processes counter */
	}
	
}
 
 
/***********************************************************************************************
**                  Variables for parameters and user control                                **
***********************************************************************************************/
 
int your_choise, use_port = 1, use_child_max = 1, child_max;
char *objs_file = NULL;
char *usrs_file = NULL;
unsigned char msg[1];
 
 
/***********************************************************************************************
**          The main() program: opens and receives new connections                          **
***********************************************************************************************/
 
 
int main (int argc, char *argv[])
{
	int port = 0, sock, fd, value;
	unsigned int client_len;
	struct sockaddr_in server, client;
	char host[40];  
	
	
	int c;
	
	opterr = 0;
	
	while ((c = getopt (argc, argv, "p:n:f:")) != -1)
		switch (c)
	{
		case 'p':
			port = atoi(optarg);
			use_port = 0;
			if ( port <= 0){
				printf("Errore: Numero di porta errato!\n");
				exit(3);
			}
			break;
			case 'n':
			child_max = atoi(optarg);
			use_child_max = 0;
			if( child_max <= 0){
				printf("Errore: Numero massimo di processi errato!\n");
				exit(3);
			}
			break;
			case 'o':
			objs_file = optarg;
			break;
			case 'u':
			usrs_file = optarg;
			break;
			case '?':
			if (optopt == 'o')
				fprintf (stderr, "il parametro -%c richiede come argomento il nome di un file di testo.\n", optopt);
			if (optopt == 'u')
				fprintf (stderr, "il parametro -%c richiede come argomento il nome di un file di testo.\n", optopt);
			if (optopt == 'p')
				fprintf (stderr, "il parametro -%c per la scelta della porta richiede come argomento un numero intero.\n", optopt);
			if (optopt == 'n')
				fprintf (stderr, "il parametro -%c per la scelta del numero massimo di processi richiede come argomento un numero intero.\n", optopt);
			else if (isprint (optopt)){
				fprintf (stderr, "\nComando sconosciuto `-%c'.\n", optopt);
				printf("\nUsage:\n%s -pPORT -nCHILD_MAX -uTEXT_FILE -oTEXT_FILE\n\n", argv[0]);
				exit(1);
			}
			else
				fprintf (stderr,
						 "Opzione carattere non riconosciuta `\\x%x'.\n",
						 optopt);
			return 1;
			default:
			abort ();
	}          
	
	
	
	if (objs_file == NULL){
		objs_file = "obj.txt";
	}
	
	if (usrs_file == NULL){
		usrs_file = "usr.dat";
	}
	
	if (use_port == 1){ 
		port = 1234;
	}
	
	if (use_child_max == 1){
		child_max = 2;
	}	  	  
	
	setbuf(stdout,NULL);		/* serve per settare a unbuffered stdout */
	
	prog = argv[0];
	
	sock = socket(AF_INET, SOCK_STREAM, 0);  /* SOCK_STREAM per TCP; */
	
	if (sock < 0)
	{
		perror("Creating a stream socket");
		exit(1);
	}
	
	
	server.sin_family = AF_INET; 
	server.sin_addr.s_addr = htonl(INADDR_ANY); 
	
	server.sin_port = htons(port);
	
	/* call SO_REUSEADDR before bind() */
	value = 1;
	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&value, sizeof(value)) < 0)
	{
		perror("during setsockopt");
		exit(5);
	}
	
	
	if (bind(sock, (struct sockaddr *) &server, sizeof(server)) < 0) 
	{
		perror("binding socket");
		exit(2); 
	}
	
	listen(sock, 10); 
	
	
	//signal(SIGTSTP, signal_handler); /* trap CTRL-Z signal */ 
	signal(SIGCHLD, signal_handler); 
	
	pid_t pid;
	
	while (1) { 
		
		client_len = sizeof(client);
		printf("\nServer in attesa\n");
		
		if ((fd = accept(sock, (struct sockaddr *) &client, &client_len)) < 0) {
			
			//perror("accepting connection");	per eventuali debug/test
			continue;			
			//exit(3);
		}
		
		
		if ( count < child_max)
		{
		
			count ++;
			sendWHO(fd);
			
			if ( (pid = fork()) == 0 )
			{		
				
				gethostname(host, 40);
				printf("Accepted client: IP= %s, port=%d, hostname= %s\n",
				inet_ntoa(client.sin_addr),
				ntohs(client.sin_port), host);
				close(sock);
				listen_client_requests(fd); 
				close(fd);
				
				exit(0);	
						/* when a child ends */
			} 
			
			else
				close(fd);
				
		}
		
		else if (count >= child_max)
		{
			sendFULL(fd);
			close(fd);
		}
		
		
	}
	
	return 0;
}
 
 
 
/***********************************************************************************************
**                         Add and Manage a Client                                            **
***********************************************************************************************/
 
 
void listen_client_requests(int fd)
{
	load_file_in_list(fd);
	char buffer[MAX_LINE];
	int lenght = 0;
		
	char *username = (char *)malloc(20*sizeof(char));
	char *password = (char *)malloc(20*sizeof(char));
	char *passwd = (char *)malloc(20*sizeof(char));
	int n = 0;
		
	
	while( (n = Readn(fd, buffer, MAX_LINE-1)) > 0)
	{
		buffer[n] = '\0';
		char *comando = buffer;
		
		lenght = strlen(comando);
		
		if(lenght ==0)
		{
			exit(0);
		}
		
	    while (comando && *comando) 
		{
			
			
			
			char *next = strstr(comando, "\r\n");
			if (next)
			{
				*next = '\0'; //Dont move next yet.
			}
			if ( lenght <= 500 )
			{   
				if ( strncmp(comando, "HELO", 4) == 0)
				{     
					
					username = comando+4;
					
					sendPASS(fd);
					
					Readn(fd, password, 16);  
					
					passwd = strtok(password, "\r\n");
					
					
					if (verify_login(username, passwd)==1)
					{
						auth=1;
						sendGOOD(fd);
					}
					else if(verify_login(username, passwd)==-1)
					{
						auth=0;
						sendFAIL(fd);
					}  
					
					
					
				}				
				
				else if ( strncmp(comando, "LIST", 4) == 0)
				{  
					display_list(llist, fd);
					
				}
				
				else if ( strncmp(comando, "QUIT", 4) == 0)
				{  
					sendBYE(fd);
					clean_list(llist);
					
					return;
				}
				
				else if(strncmp(comando, "FIND", 4) == 0)
				{  
					
					   
					
					if (auth == 0) 
					{
						sendNAUT(fd);
					}
					
					
					else if (llist ->next != NULL)
					{   
					    	
						char * temp = comando+4;
						uint16_t arr;
						unsigned int val=0;
						sendHERE(fd);						
						int found;
						uint16_t net;
						
						
						for (; temp != '\0'; temp+=2)
						{							
							
							memcpy(&arr, temp, 2);
							
							val = ntohs(arr);
							
							if ( val != 0)
							{
							Writen(fd, &arr, 2);
							}
							else if ( val == 0)
							{
							break;
							}
							
							
							found = search_value(llist, val, fd);       
							if ( found != 0 )
							{
							net = htons(found);                               
							
							Writen(fd, &net, sizeof(net));
							
							}
							
							
							
						}                               
					}
				}
				
			else 
			{
			sendWHAT(fd);
			}	
				
				
			}
			
			if (next)
				comando = next + 2; //move to next command here
			    
			else
				comando = NULL; // could as well have used break here
		}
	}    
	
	
	
}
 
 
/***********************************************************************************************
**                       Open and Load data into the Linked List                              **
***********************************************************************************************/
 
void load_file_in_list(fd)
{
	
	llist = (struct NODE *)malloc(sizeof(struct NODE));
	llist->code = 0;
	llist->next = NULL;
	llist->size = 0;
	llist->line = 0;  
	
	FILE * pFile;
	char buffer [1000];
	int code;
	char name[1000];
	
	
	pFile = fopen (objs_file , "r");
	
	if (pFile == NULL)
	{
		perror ("Error opening file");
	}
	else
	{
		while ( fgets (buffer , 100 , pFile) != NULL )
		{
			
			sscanf(buffer,"%d %s \n", &code, name); // is it correct to use also \n ? 
			linea++;
			append_node(llist, name, code, linea); // insert values in the list */
			size++;
		}
		
		fclose (pFile);
	}
	
}
 
int verify_login(char * usern, char * pass)
{
	
	char entry[32];
	char username[17] = { 0 }; // 17 or 16 chars?
	char password[17] = { 0 };
	char * temp = (char *)malloc(17*sizeof(char));;
	
	FILE * passfile = fopen(usrs_file, "r");
	
	if ( passfile == NULL)
	{
		return -1;	
	}   
	
	
	while (fread(entry, 1, 32, passfile))
	{
		
		strncpy (username, entry, 16);
		username[16]='\0';
		temp = strchr(username, '~');
		if (temp)
			*temp = '\0';
		
		strncpy (password, &entry[16], 16);
		password[16]='\0';
		temp = strchr(password, '~');
		if (temp)
			*temp = '\0';
		
		if (strcmp(usern, username) == 0 &&
			strcmp(pass, password) ==0 )
		{
			fclose(passfile);
			return 1;
		}
		
	}
	
	fclose(passfile);
	return -1;
	
}
Related Solutions
Related Solutions
 
Loading Advertisement...
 

Rank: Sage

Accepted Solution by Kdo:

All comments and solutions are available to Premium Service Members only.

Start your 7-day free trial and see for yourself why Experts Exchange is the easiest and most proven technology resource in the world. Get Started

Already a member? Login to view this solution.

 
 
Author Comment by roccogalati:

All comments and solutions are available to Premium Service Members only.

Start your 7-day free trial and see for yourself why Experts Exchange is the easiest and most proven technology resource in the world. Get Started

Already a member? Login to view this solution.

 
 

Rank: Sage

Expert Comment by Kdo:

All comments and solutions are available to Premium Service Members only.

Start your 7-day free trial and see for yourself why Experts Exchange is the easiest and most proven technology resource in the world. Get Started

Already a member? Login to view this solution.

 
 

Rank: Sage

Assisted Solution by sunnycoder:

All comments and solutions are available to Premium Service Members only.

Start your 7-day free trial and see for yourself why Experts Exchange is the easiest and most proven technology resource in the world. Get Started

Already a member? Login to view this solution.

 
 
Author Comment by roccogalati:

All comments and solutions are available to Premium Service Members only.

Start your 7-day free trial and see for yourself why Experts Exchange is the easiest and most proven technology resource in the world. Get Started

Already a member? Login to view this solution.

 
Loading Advertisement...
20080924-EE-VQP-41 / EE_QW_2_20070628