25. juli 2003 - 12:45
Der er
21 kommentarer og 1 løsning
sende tilbage til alle clineter
jaa.. nu har jeg fået lavet mig en server der sender til bage til den client der sendte det... hvordan får man så den til at sende til alle clienter (til chat ala IRC) håber i kan hjælpe... og hvordan sender man tekst med mellemrum og hvordan tømmer man en "char recvbuf[256];" /mad_man kode kommer lige om 2 sec
Annonceindlæg fra Capgemini
#include <winsock.h> #include <iostream> #define MAXCONN 10 using namespace std; const int kBufferSize = 1024; DWORD WINAPI Echo(void* sock_) { SOCKET sock = (SOCKET)sock_; char acReadBuffer[kBufferSize]; int nReadBytes; do { nReadBytes = recv(sock, acReadBuffer, kBufferSize, 0); if (nReadBytes > 0) { cout << "Received " << nReadBytes << " bytes from client." << endl; int nSentBytes = 0; while (nSentBytes < nReadBytes) { int nTemp = send(sock, acReadBuffer + nSentBytes, nReadBytes - nSentBytes, 0); if (nTemp > 0) { cout << "Sent " << nTemp << " bytes back to client." << endl; nSentBytes += nTemp; } else if (nTemp == SOCKET_ERROR) { return false; } else { cout << "Peer unexpectedly dropped connection!" << endl; return true; } } } else if (nReadBytes == SOCKET_ERROR) { return false; } } while (nReadBytes != 0); cout << "Connection closed by peer." << endl; return true; } void accptconn(SOCKET lytter) { sockaddr_in sinRemote; int nAddrSize = sizeof(sinRemote); while (1) { SOCKET sock = accept(lytter, (sockaddr*)&sinRemote, &nAddrSize); if (sock != INVALID_SOCKET) { cout << "Accepted connection from " << inet_ntoa(sinRemote.sin_addr) << ":" << ntohs(sinRemote.sin_port) << "." << endl; DWORD nThreadID; CreateThread(0, 0, Echo,(void*)sock, 0, &nThreadID); } } } int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmd, int nShow) { WORD sockVersion; WSADATA wsaData; int sock; sockVersion = MAKEWORD(1, 1);// WORD (1, 1); WSAStartup(sockVersion, &wsaData); SOCKET lytter; lytter = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if(lytter == INVALID_SOCKET) { WSACleanup(); return 0; } SOCKADDR_IN srvinf; srvinf.sin_family = AF_INET; srvinf.sin_addr.s_addr = INADDR_ANY; srvinf.sin_port = htons(8888); sock = bind(lytter, (LPSOCKADDR)&srvinf, sizeof(struct sockaddr)); if(sock == SOCKET_ERROR) { WSACleanup(); return 0; } sock = listen(lytter, MAXCONN); if(sock == SOCKET_ERROR) { WSACleanup(); return 0; } accptconn(lytter); }
Du opsamler alle dine klienter i en liste (dvs. når en klient connecterblir den adderet i en liste). Så laver du bare en for-loop som skriver til klienterne i listen
hov glømte og sige er lidt ny til det her c++ værk... så der må gerne komme en lille linje kode eller 2 som exempel tak =)
Hvis du skal sende til alle klienter er du nød til at sende til hver klient socket. Der burde ikk evære nogen som helst problemer med at sende tekster med mellemrumn i (man sender med en adresse og en længde - og de data sendes uanset mellemrum nul bytes og andet). strcpy(recvbuf,""); sætter recvbuf til en tom streng.
noget ala for (int count = 0; count < array->GetSize() ; count++){ Klient * klient = (Klient*)array->GetAt(i); klient->SendMessage("Hejsa"); } hvor Klient er den klasse som repræsenterer din klient og array er en tabel/liste med alle forbundne klienter
char exit[] = "exit"; char buffer[256]; ZeroMemory(buffer, 256); do { cout << "skriv noget:"; cin >> buffer; nret = send(theSocket,buffer,strlen(buffer),0); //strlen(buffer) }while( strcmp(exit,buffer) !=0); skulle det der ik du til og sende med mellemrum ????
hvis du nu kikker i det kode jeg allerrede har skrevet.. kan det bruges til og sende til alle klienter og hvordan...
Det er udmærket til at sende mellemrum med ud over socket. *MEN* cin >> buffer læser kun det første ord in !
hvordan får jeg den sA til at læse alle ord ind ???
25. juli 2003 - 13:12
#10
Hvis du vil have en hel linie, så brug: cin.getline metoden.
25. juli 2003 - 13:14
#11
25. juli 2003 - 13:17
#12
repsaks løsning er en high-level OO løsning bruger en avanceret data struktur til at have listen. Din kode er tæt på ren C (du bruger cin/cout, // og erklæring midt i koden fra C++). Det er ligesom 2 forskellige måder at gribe det an på.
25. juli 2003 - 13:21
#13
Hvis du skal lave noget tilsvarende, så skal det vær enoget i stil med: SOCKET sock[100]; int nsock; void accptconn(SOCKET lytter) { sockaddr_in sinRemote; int nAddrSize = sizeof(sinRemote); nsock=0; while (1) { sock[nsock] = accept(lytter, (sockaddr*)&sinRemote, &nAddrSize); if (sock[nsock] != INVALID_SOCKET) { cout << "Accepted connection from " << inet_ntoa(sinRemote.sin_addr) << ":" << ntohs(sinRemote.sin_port) << "." << endl; DWORD nThreadID; CreateThread(0, 0, Echo,(void*)sock[nsock], 0, &nThreadID); nsock++; } } } og så kan du lave en for løkke fra 0 til nsock og bruge sock.
25. juli 2003 - 13:38
#14
nu kommer der en fejl når jeg prøver at kompile.. den kommer i: SOCKET sock[nsock] = accept(lytter, (sockaddr*)&sinRemote,&nAddrSize); 57 C:\Documents and Settings\Mad_Man\Skrivebord\Chat prog\main.cpp variable-sized object `sock' may not be initialized
25. juli 2003 - 14:14
#15
det er i ,&nAddrSize fejlen ligger men hvad fejler den ???
25. juli 2003 - 14:25
#16
hvad gør SOCKET sock[100]; linjen ---- og hvorfor tallet 100
25. juli 2003 - 14:34
#17
sock[nsock] = ikke SOCKET sock[nsock] = fordi jeg har flyttet erklæringen op som global variabel, så andre funktione rkan bruge den.
25. juli 2003 - 14:35
#18
SOCKET sock[100]; sætter plads af til 100 SOCKET's og kan dermed klare 100 clients.
25. juli 2003 - 15:48
#19
er jeg kørt helt i skoven ??? DWORD WINAPI Echo(void* sock_) { SOCKET sock = (SOCKET)sock_; char acReadBuffer[kBufferSize]; int nReadBytes; while(1) { nReadBytes = recv(sock, acReadBuffer, kBufferSize, 0); if (nReadBytes > 0) { cout << "Received " << nReadBytes << " bytes from client." << endl; for (int count = 0; count < nsock ; count++){ int nSentBytes = 0; while (nSentBytes < nReadBytes) { int nTemp = send(sock, acReadBuffer + nSentBytes,nReadBytes - nSentBytes, 0); if (nTemp > 0) { cout << "Sent " << nTemp << " bytes back to client." << endl; nSentBytes += nTemp; } else if (nTemp == SOCKET_ERROR) { return false; } else { cout << "Peer unexpectedly dropped connection!" << endl; return true; } } } } else if (nReadBytes == SOCKET_ERROR) { return false; } } while (nReadBytes != 0); cout << "Connection closed by peer." << endl; return true; } det sender bare 2 echos tilbage hvis der er 2 clienter på.. men det sender ik til den anden client:(
25. juli 2003 - 16:04
#20
Du "skygger" for den globale variabel.
25. juli 2003 - 16:06
#21
Altså skal du lavet noget a la (bare copy paste og rettet i browser): DWORD WINAPI Echo(void* sock_) { SOCKET thissock = (SOCKET)sock_; char acReadBuffer[kBufferSize]; int nReadBytes; while(1) { nReadBytes = recv(thissock, acReadBuffer, kBufferSize, 0); if (nReadBytes > 0) { cout << "Received " << nReadBytes << " bytes from client." << endl; for (int count = 0; count < nsock ; count++){ int nSentBytes = 0; while (nSentBytes < nReadBytes) { int nTemp = send(sock[count], acReadBuffer + nSentBytes,nReadBytes - nSentBytes, 0); if (nTemp > 0) { cout << "Sent " << nTemp << " bytes back to client." << endl; nSentBytes += nTemp; } else if (nTemp == SOCKET_ERROR) { return false; } else { cout << "Peer unexpectedly dropped connection!" << endl; return true; } } } } else if (nReadBytes == SOCKET_ERROR) { return false; } } while (nReadBytes != 0); cout << "Connection closed by peer." << endl; return true; }
25. juli 2003 - 16:09
#22
ahhh jeg takker 1000 gange for hjælpen... nu funker det som det skal... jeg har også lært en del ved det her =)
Kurser inden for grundlæggende programmering