Avatar billede quiw Nybegynder
25. december 2006 - 15:58 Der er 10 kommentarer og
1 løsning

Receive Loop.

Jeg kan simpelthen ikke gennemskue hvorfor det ikke virker:

    char input[10];
    char buf[100];
    while(input!="\n")
    {
        recv(sd2, input, sizeof(input),0);
        sprintf(buf,"%s%s",buf,input);
    }
    send(sd2,"Indhold af buf: ",strlen("Indhold af buf: "),0);
    send(sd2,buf,strlen(buf),0);

1. Den hopper ikke ud af loopet når den modtager et linjeskift.
2. Når jeg tjekker hvad input og buf indeholder, så indeholder de begge bare en masse underlige tegn.
3. Kan nogle løse mit problem, uden at ændre for meget og stadig holde det simpelt?

På forhånd tak.
Avatar billede Slater Ekspert
25. december 2006 - 16:30 #1
input vil altid indeholde 10 tegn og buf 100 fordi du har defineret dem sådan. Når du udskriver den, stoppes der bare ved det første nullchar ( \0 ).
Avatar billede quiw Nybegynder
25. december 2006 - 16:55 #2
Okay, men hvad kan jeg ellers gøre så?
Avatar billede arne_v Ekspert
25. december 2006 - 17:21 #3
char input[10] = "";
    char buf[100] = "";
    while(strstr(input,"\n")!=NULL)
    {
        n = recv(sd2, input, sizeof(input),0);
        input[n] = '\0';
        strcat(buf,input);
    }
    send(sd2,"Indhold af buf: ",strlen("Indhold af buf: "),0);
    send(sd2,buf,strlen(buf),0);

måske
Avatar billede quiw Nybegynder
27. december 2006 - 13:27 #4
arne_v - Den mangler definitionen på n variablen og den siger invalid conversion from const char to char ved input[n]="\0";
Avatar billede arne_v Ekspert
27. december 2006 - 13:36 #5
n skal erklæres som int

det er '\0' ikke "\0"
Avatar billede quiw Nybegynder
27. december 2006 - 13:55 #6
Hm .. Kan ikke umiddelbart få det til at virke, og kan ikke gennemskue hvorfor .. Min fulde kode ser således ud:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <windows.h>

using namespace std;


const int MAXCLI=10000;

// Loop funktion til at recieve input.
void* recv(void *p)
{
    int n;
    int sd2=*((int*)p);
    char input[10]="";
    char buf[100]="";
    while(strstr(input, "\n")!=NULL)
    {
      n=recv(sd2,input,sizeof(input),0);
      input[n]='\0';
      strcat(buf,input);
    }
    return buf;
}

// Selve client delen.
DWORD __stdcall client(void *p)
{
    char input[100];
    int sd2=*((int*)p);
   
    send(sd2,"Indtast besked: \r\n",strlen("Indtast besked: \r\n"),0);
    sprintf(input,"%s",recv(p));
    send(sd2,"Din besked var: ",strlen("Din besked var: "),0);
    send(sd2,input,strlen(input),0;
   
    send(sd2,"Indtast besked igen: \r\n",strlen("Indtast besked igen: \r\n"),0);
    sprintf(input,"%s",recv(p));
    send(sd2,"Din besked var: ",strlen("Din besked var: "),0);
    send(sd2,input,strlen(input),0;
   
    Sleep(10000);
    closesocket(sd2);
    return 0;
}

// Main delen.
int main()
{
    WSADATA WSAData;
    WSAStartup(0x0101,&WSAData);
    int sd=socket(AF_INET,SOCK_STREAM,0);
    if(sd<0)
    {
        cout << "Could not create socket: " << strerror(errno) << endl;
    }
    int status;
    struct sockaddr_in local;
    local.sin_family=AF_INET;
    local.sin_port = htons(1234);
    local.sin_addr.s_addr = INADDR_ANY;
    status=bind(sd,(struct sockaddr *)&local,sizeof(local));
    if(status<0)
    {
        cout << "Could not bind socket: " << strerror(errno) << endl;
    }
    status=listen(sd,5);
    if(status<0)
    {
        cout << "Could not listen to socket: " << strerror(errno) << endl;
    }
    int sd2[MAXCLI];
    int n=0;
    while(1)
    {
        sd2[n]=accept(sd,0,0);
        if(sd2[n]<0)
        {
            cout << "Could not accept socket: " << strerror(errno) << endl;
        }
        cout << "Client connected" << endl;
        DWORD id;
        CreateThread(0, 0, client, (LPVOID)&sd2[n], 0, &id);
    }
  WSACleanup();
  return 0;
}

- Hele princippet er, at der er en funktion som man hurtigt kan bruge til at recieve, i stedet for at skulle skrive heeele loopet hvergang man geren vil modtage noget fra clienten .. Således at man f.eks. kan
Send ("Indtast bruger: ")
Recv > Brugernavn;

Send ("Hej "<<brugernavn<<" indtast password");
Recv > Password;
Avatar billede quiw Nybegynder
27. december 2006 - 19:04 #7
Eller kan man på nogen måde sende en besked til clienten som kører telnet, som gør at telnet skifter til "new line mode" ? Hvilket gør at loopet bliver overflydigt ..
Avatar billede quiw Nybegynder
28. december 2006 - 00:48 #8
Nej okay, har selv fundet en løsning .. Men er stødt ind i et nyt problem:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <windows.h>


using namespace std;

const int MAXCLI=10000;
char CHATMSG[10000];
int newmsg = 0;
int onlineusers = 0;

char* recv(void *p)
{
    int sd2=*((int*)p);
    int ix=0;
    int len;
    char buf[500];
    char input[500];
    memset(buf,0x00,sizeof(buf));
    while((len=recv(sd2,buf+ix,sizeof(buf)-ix,0))>0)
    {
        ix=ix+len;
        if(strstr(buf,"\r\n")!=NULL)
        {
            char cmd[500];
            int cmdlen = (strstr(buf,"\r\n")-buf)+strlen("\r\n");
            memset(cmd,0x00,sizeof(cmd));
            memmove(cmd,buf,cmdlen);
            memmove(buf,buf+cmdlen,ix-cmdlen);
            ix=ix-cmdlen;
            memset(buf+ix,0x00,sizeof(buf)-ix);
            sprintf(input,"%s",cmd);
            break;
        }
    }
    return input;
}

DWORD __stdcall msgsend(void *p)
{
    int sd2=*((int*)p);
    while(1)
    {
                if(newmsg==1)
                {
                    send(sd2,CHATMSG,strlen(CHATMSG),0);
                    //Sleep(100);
                    newmsg=0;
                }
                else
                {
                    //Sleep(100);
                }
    }
}

DWORD __stdcall client(void *p)
{
    int sd2=*((int*)p);
    char *test;
    bool online=true;
    char user[100];
    cout << "Client logged in \n";
    send(sd2,"Welcome online to Quiw's demo-chat-server-kind-a-thing \r\n",strlen("Welcome online to Quiw's demo-chat-server-kind-a-thing \r\n"),0);
    send(sd2,"Please enter your name: ",strlen("Please enter your name: "),0);
    test=recv(p);
    send(sd2,"\r\nHello ",strlen("\r\nHello "),0);
    send(sd2,test,strlen(test),0);
    send(sd2,"Please start chatting :) \r\n",strlen("Please start chatting :) \r\n"),0);
    send(sd2,"-------------------------------------------\r\n",strlen("-------------------------------------------\r\n"),0);
    DWORD id2;
    CreateThread(0, 0, msgsend, (LPVOID)&sd2, 0, &id2);
    strcpy(CHATMSG,"#1 user has connected\n\r");
    onlineusers = onlineusers + 1;
    newmsg=1;
    while(online==true)
    {
        test=recv(p);
        if(strcmpi(test,"QUIT")==0)
            {
                send(sd2,"Test",strlen("Test"),0);
                closesocket(sd2);
                cout << "Client disconnected" << endl;
                strcpy(CHATMSG,"#1 user has disconnected\n\r");
                onlineusers = onlineusers - 1;
                newmsg=1;
                break;
            }
           
            else if(strcmpi(test,"ONLINEUSERS")==0)
            {
                send(sd2,"There is: ",strlen("There is: "),0);
                sprintf(test,"%d",onlineusers);
                send(sd2,test,strlen(test),0);
                send(sd2," users online.\n\r",strlen(" users online.\n\r"),0);
            }
           
            else
            {
                strcpy(CHATMSG,test);
                newmsg=1;
            }
    }       
    Sleep(10000);
    closesocket(sd2);
    return 0;
}


int main()
{
    int sd2[MAXCLI];
    int status;
    int n=0;
    int sd;
    WSADATA WSAData;
    WSAStartup(0x0101,&WSAData);
    sd=socket(AF_INET,SOCK_STREAM,0);
    struct sockaddr_in local;
    local.sin_family=AF_INET;
    local.sin_port = htons(1234);
    local.sin_addr.s_addr = INADDR_ANY;
    bind(sd,(struct sockaddr *)&local,sizeof(local));
    listen(sd,5);
    while(1)
    {
        sd2[n]=accept(sd,0,0);
        DWORD id;
        CreateThread(0, 0, client, (LPVOID)&sd2[n], 0, &id);
    }
    WSACleanup();
    return 0;
}

- Det fungere sådan set fint .. Men når der kommer 2 clienter på .. Så kan den ikke finde ud af beskederne .. Den blander alle beskederne sammen og faktisk er det kun 1 tlifældig der modtager beskeden .. Hvis f.eks. 5 clienter er online, vil kun den 1 modtage beskeden .. Selvom den er sendt til alle ..
Avatar billede quiw Nybegynder
28. december 2006 - 00:50 #9
- Har løst første problem med at den blander bogstaverne sammen, men den sender stadig kun til 1 tilfældig ud af 5 .. Nogle der kan hjælpe?, skal der flere point på?
Avatar billede quiw Nybegynder
29. december 2006 - 13:43 #10
- Ah okay, har løst alle problemerne selv .. Men tak for hjælpen alligevel :) Smid et svar arne_v.
Avatar billede arne_v Ekspert
29. december 2006 - 19:12 #11
ok
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester