[c++] mały czacik na telnecie

0

witam zrobiłem na potrzeby mojej grupy programik czacik z klijętem typu telnet tzn odpalam "serwer" ;] i wszyscy sie łącza wpisując "telnet host 3090" każdy user ma swoje id i wiadomości od niego są wyświetlane w postaci "id:txt" takie moje pytanko jak to zoptymalizować, co dodać (myślałem o przesyłaniu plików wideo i odtwarzaniu w oknie klienta ale chyba nie da rady [rotfl]).
ps główny problem jest przekazywanie parametru do wątku bo jak dawałem &home[users] to zawsze wskazywało na home[0] a może ja czegoś nie doczytałem.
za wszelkie poprawki dzięki.

#include <cstdlib>
#include <iostream>
#include <winsock.h>
#include <time.h>
#define bufor_usera 200
#define user_max 30
using namespace std;
struct user{
	   SOCKET s;
	   struct sockaddr_in addr;
	   char buf[bufor_usera];
	   char nick[10];
	   int id;
	   bool w_r;
	   DWORD idThread;
 	   HANDLE thread;
	   }p_buf;
typedef struct user user; 
struct s_txt{
	   char buf[bufor_usera];
	   int who;
	   char to[10];
	   int size;
	   };
typedef struct s_txt s_txt;
CRITICAL_SECTION brodcast;
int users;
user* home[user_max];
int usend(SOCKET dest,char * txt,int size){
	int i=size,result;
	for (result=0;size>0/*&& !result*/;--size)
	     result=send(dest,&txt[i-size],1,0);
	return result;	};
DWORD WINAPI procedura_rozsylania_textu(void*dane){
	  int i;
	  s_txt *my;
	  my=(s_txt*)dane;
	  char t[3];
	  sprintf(t,"%d:",my->who);
	  EnterCriticalSection(&brodcast);
	   for(i=0;i<users;++i)if(my->who!=i){
		  					usend(home[i]->s,t,2);
		  					usend(home[i]->s,my->buf,my->size);};
      LeaveCriticalSection(&brodcast);}
DWORD WINAPI procedura_obslugi_usera(void*dane){
      int result=1,i=0,iam;
      char buf[5];
      s_txt p;
      iam=users-1;
      p.who=iam;
      printf("id == %d ",iam);
	 while((result!=0)&&(true)){
	 while((home[iam]->buf[i-1]!='\n')){
	      result = recv (home[iam]->s, buf, 1, 0 );
	  	  home[iam]->buf[i]=buf[0];
		  if((buf[0]=='~')) {usend(home[iam]->s,home[iam]->buf,i);i-=1;} 
		  if((buf[0]=='.')&&(i==0))goto localquit; // wylogowanie 
		  if((buf[0]=='/')&&(i==0))home[iam]->w_r=!home[iam]->w_r;
		  if ((buf[0]=='\b')&&(i>0)){home[iam]->buf[i]='\0';i-=2;}
		  ++i;}
     home[iam]->buf[i]='\0';
     printf("%d:%s",iam,home[iam]->buf);
     p.size=i;
	 memcpy(p.buf,home[iam]->buf,bufor_usera);
     CreateThread(NULL,NULL,procedura_rozsylania_textu,&p,NULL,NULL);
	 memset(home[iam]->buf,'\0',bufor_usera);
     i=0;}
  localquit:printf("user:%d disconect",home[iam]->id);
  shutdown (home[iam]->s,2);}
int main(int argc, char *argv[])
{
 	users=0;
	int result;
	SOCKET sock,sock2;
 	char err_in_loc='_';
 	char buf[255];
	char buft[200];
	char t[]="ł";
    int i=0;
   	DWORD idThread,idThread2;
 	HANDLE thread,thread2;
 	InitializeCriticalSection(&brodcast);
 	struct sockaddr_in addr;
 	addr.sin_family			= AF_INET ;
	addr.sin_port			= htons ( 3090 );
	addr.sin_addr.s_addr	= INADDR_ANY;//inet_addr("127.0.0.1") ;
	memset(&(addr.sin_zero), '\0' ,8 ) ;
    int sin_size = sizeof(struct sockaddr_in);
	WSADATA wsaData ;
	result=WSAStartup ( MAKEWORD (1,1), &wsaData ) ;
	if (result==SOCKET_ERROR) ;
//	   {err_in_loc='i';goto ext;}
	sock = socket ( AF_INET, SOCK_STREAM, IPPROTO_TCP) ;
	if (sock==INVALID_SOCKET)
	   {err_in_loc='s';goto ext;}
	result = bind ( sock, (struct sockaddr * ) &addr,sin_size) ;
	if (result==SOCKET_ERROR) 
	   {err_in_loc='b';goto ext;}
serch_user:
    Sleep(1000);
	result=listen(sock,2);
	if (result==INVALID_SOCKET)
	   {err_in_loc='l';goto ext;}
	home[users]=new user;
	home[users]->id=users;
	home[users]->addr.sin_family		= AF_INET ;
	home[users]->addr.sin_port			= htons ( 3090 );
	home[users]->addr.sin_addr.s_addr	= INADDR_ANY ;
	memset(&(home[users]->addr.sin_zero), '\0' ,8 ) ;
	printf("user %d \n",users);
	home[users]->s = accept (sock, (struct sockaddr *) &home[users]->addr, &sin_size) ;	
	if (home[users]->s==SOCKET_ERROR) printf("sozcket user creat err ");
//	   {err_in_loc='a';goto ext;};
    home[users]->w_r=false;
    home[users]->thread=CreateThread(NULL,NULL,procedura_obslugi_usera,&home[users],NULL,&home[users]->idThread);
	++users;
goto serch_user;	
	system("PAUSE");
ssw:
cler:	result=shutdown ( sock,2 ) ;
	    WSACleanup () ;
	    goto fquit;
ext:    printf("You Have err in %c, err: %d",err_in_loc,WSAGetLastError());
	    system("PAUSE");
	    goto cler;
fquit:	return EXIT_SUCCESS;
}

ps wychodzi sie kropką w nowej lini
jak by sie nic w klijencie nie pojawiało napisac coś potem "~" i powinno być ok

0

ps prog na zasadzie copyleft

0

Ja pierniczę, to tutejsze formatowanie tak rozwala kod czy ty nigdy nie słyszałeś o czytelności kodu...?

// formatowanie kodu dziala dobrze :) [mf]

0

plików wideo i odtwarzaniu w oknie klienta ale chyba nie da rady

a to co, jak nie Star Wars Ascii? telnet towel.blinkenlights.nl

tutejsze formatowanie tak rozwala
Takie formatowanie wypluwa dev-cpp, nie jest wpełni wyposażone w obsłuję TAB'a i sam zmienia \t na spacje gdy coś wkleisz zamiast napisać na początku linii.

Jak optymalizować? Zastanów się dobrze waćpan, co taki serwer robić ma i podziel go na osobne bloki, które mogą być wielokrotnie używane.

Wklej swój kod do notatnika, popraw taby z napraw swój post, bo czytać się nie da.

0
#include <cstdlib>
#include <iostream>
#include <winsock.h>
#include <time.h>
#define bufor_usera 200
#define user_max 30
#define HAVEN 3090
   using namespace std;
    struct user{
      SOCKET s;
      struct sockaddr_in addr;
      char buf[bufor_usera];
      char nick[10];
      int id,i;
      DWORD idThread;
      HANDLE thread;
      };
   typedef struct user user; 
    struct s_txt{
      char buf[bufor_usera];
      int who;
      char to[10];
      int size;
      };
   typedef struct s_txt s_txt;
   CRITICAL_SECTION brodcast;
   int users;
   user* home[user_max];

    int usend(SOCKET dest,char * txt,int size){
      int i=size,result;
      result=send(dest,txt,size,0);	     
      return result;	};

    DWORD WINAPI procedura_rozsylania_textu(void*dane){
      int i,j;
      s_txt *my;
      my=(s_txt*)dane;
      char t[3],k[4]="\b \b";
      sprintf(t,"%d:",my->who);
      EnterCriticalSection(&brodcast);
      for(i=0;i<users;++i)
         if(my->who!=i){
            for(j=0;j<home[i]->i;j++)send(home[i]->s,k,3,0);
         //if(home[i]->nick[0]!='\0')
         //send(home[i]->s,home[i]->nick,sizeof(home[i]->nick),0);
         //else
            send(home[i]->s,t,2,0); 
            send(home[i]->s,my->buf,my->size,0);
            send(home[i]->s,home[i]->buf,home[i]->i,0);
         };
      LeaveCriticalSection(&brodcast);}
      
    DWORD WINAPI procedura_obslugi_usera(void*dane){
      int result=1,iam;
      char buf[5];
      s_txt p;
      iam=users-1;
      p.who=iam;
      home[iam]->i=0;
      printf("id == %d ",iam);
      while((result!=0)&&(true)){
         while((home[iam]->buf[home[iam]->i-1]!='\n')){
            result = recv (home[iam]->s, buf, 1, 0 );
            home[iam]->buf[home[iam]->i]=buf[0];
            if((buf[0]=='~')){
               usend(home[iam]->s,home[iam]->buf,home[iam]->i);
               home[iam]->i-=1;} //Sleep(1000);//send(sock2,t,result,0);
            if((buf[0]=='.')&&(home[iam]->i==0))
               goto localquit; // wylogowanie 
         //if((buf[0]=='/')&&(home[iam]->i==0));
            if ((buf[0]=='\b')&&(home[iam]->i>0)){
               home[iam]->buf[home[iam]->i]='\0';
               buf[0]=' ';buf[1]='\b';
               home[iam]->i-=2;
               send(home[iam]->s,buf,2,0);/*buf[0]='\b';send(home[iam]->s,buf,result,0);*/}
            ++home[iam]->i;
         }
         home[iam]->buf[home[iam]->i]='\0';
      //     if(home[iam]->buf[0]=='/'){for(result=1;((result<10)&&(home[iam]->buf[result]!='\n')&&(home[iam]->buf[result]!='\0'));++result)home[iam]->nick[result-1]=home[iam]->buf[result];printf("set nickname");}
         printf("%d:%s",iam,home[iam]->buf);
         p.size=home[iam]->i;
         memcpy(p.buf,home[iam]->buf,bufor_usera);
         CreateThread(NULL,NULL,procedura_rozsylania_textu,&p,NULL,NULL);
         memset(home[iam]->buf,'\0',bufor_usera);
         home[iam]->i=0;}
   localquit:
      printf("\t User:%d It has committed suicide \n",home[iam]->id);
      shutdown (home[iam]->s,2);}
  
  
    int main(int argc, char *argv[])
   {
      users=0;
      int result;
      SOCKET sock;
      char err_in_loc='_';
      char buf[255];
      char buft[200];
      char t[]="ł";
      int i=0;
      DWORD idThread;
      HANDLE thread;
      InitializeCriticalSection(&brodcast);
      struct sockaddr_in addr;
      addr.sin_family			= AF_INET ;
      addr.sin_port			= htons ( 3090 );
      addr.sin_addr.s_addr	= INADDR_ANY;//inet_addr("127.0.0.1") ;
      memset(&(addr.sin_zero), '\0' ,8 ) ;
      int sin_size = sizeof(struct sockaddr_in);
      WSADATA wsaData ;
   
      result=WSAStartup ( MAKEWORD (1,1), &wsaData ) ;
      if (result==SOCKET_ERROR){
         err_in_loc='i';
         goto ext;}
      sock = socket ( AF_INET, SOCK_STREAM, IPPROTO_TCP) ;
      if (sock==INVALID_SOCKET){
         err_in_loc='s';
         goto ext;}
      result = bind ( sock, (struct sockaddr * ) &addr,sin_size) ;
      if (result==SOCKET_ERROR){
         err_in_loc='b';
         goto ext;}
   serch_user:
      Sleep(1000);
      result=listen(sock,2);
      if (result==INVALID_SOCKET){
         err_in_loc='l';
         goto ext;}
      home[users]=new user;
      home[users]->id=users;
      home[users]->addr.sin_family		= AF_INET ;
      home[users]->addr.sin_port			= htons ( 3090 );
      home[users]->addr.sin_addr.s_addr	= INADDR_ANY ;
      memset(&(home[users]->addr.sin_zero), '\0' ,8 ) ;
      home[users]->nick[0]='\0';
      printf("user %d \n",users);
      home[users]->s = accept (sock, (struct sockaddr *) &home[users]->addr, &sin_size) ;	
      if (home[users]->s==SOCKET_ERROR){
         printf("This user is stupid!!");
         err_in_loc='a';
         goto ext;};
      home[users]->thread=CreateThread(NULL,NULL,procedura_obslugi_usera,&home[users],NULL,&home[users]->idThread);
      ++users;
      if((users<user_max)&& true) 
         goto serch_user;	
   // true trzeba zastapić jakimś sensownym warunkiem kontynuacji
      system("PAUSE");
   ssw:
   cler:   DeleteCriticalSection(&brodcast);
      result=shutdown ( sock,2 ) ;
      WSACleanup () ;
      for(int itniewiempoco=0;itniewiempoco<users;++itniewiempoco)
         delete home[itniewiempoco];
      goto fquit;
   ext:    printf("You Have err in %c, err: %d",err_in_loc,WSAGetLastError());
      system("PAUSE");
      goto cler;
   fquit:	
      return EXIT_SUCCESS;
   }

mam nadzieje ze lepiej :)
sapero masz jakiś programik do przerabiania np avi na ascii art 80x25 ?? :D
a jeśli chodzi o optymalizacje to zawsze byłem kiepski :(

1 użytkowników online, w tym zalogowanych: 0, gości: 1