Wählen Sie mit(..) auf client
Ich versuche zu implementieren, wählen Sie(..) auf der client-Seite mit dem erstellen von mehreren sockets abgesehen von den TCP-socket zu empfangen(..) vom server. Ich möchte Daten empfangen, die auf unterschiedlichen recv(..) von verschiedenen sockets erstellt mit select(..). Der code scheint nicht zu funktionieren, wie erwartet. Bitte helfen Sie. Danke!
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<netinet/in.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
int count, createsocket, chunks, newsocket[5], i;
int bufsize = 2048;
char *buffer = malloc(bufsize);
char fname[256];
struct sockaddr_in address;
fd_set master;
fd_set read_fds;
int fdmax, j;
FD_ZERO(&master);
FD_ZERO(&read_fds);
if((createsocket = socket(AF_INET, SOCK_STREAM, 0)) > 0)
{
printf("Socket created.\n");
}
address.sin_family = AF_INET;
address.sin_port = htons(15001);
inet_pton(AF_INET, argv[1], &address.sin_addr);
if(connect(createsocket, (struct sockaddr*)&address, sizeof(address)) == 0)
{
printf("Connected to server %s\n",argv[1]);
}
printf("Enter the file name to download\n");
scanf("%s",fname);
send(createsocket, fname, sizeof(fname), 0);
// printf("Enter the chunks of file to receive");
printf("waiting to receive the file from server..\n");
//code to create a new socket based on the number of chunks required
for(i=0;i<4;i++)
{
if((newsocket[i] = socket(AF_INET, SOCK_STREAM, 0)) > 0)
{
printf("new Socket %d created.\n", i);
}
}
FD_SET(createsocket, &master);
fdmax = createsocket;
for(;;)
{
read_fds = master;
if(select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1){
perror("select");
exit(2);
}
for(i=0; i<=fdmax; i++){
if(FD_ISSET(i, &read_fds)) {
if(i == createsocket) {
printf("something is happening..\n");
if(newsocket[i] == -1){
printf("socket %d\n",i);
} else {
FD_SET(newsocket[i], &master);
if(newsocket[i] > fdmax) {
fdmax = newsocket[i];
}
printf("still something is going on..\n");
}
} else {
printf("Doing something..\n");
for(j = 0; j <= fdmax; j++) {
if(FD_ISSET(j, &master)) {
if(j!= createsocket && j!= i) {
if((count = recv(createsocket, buffer, bufsize, 0)) > 0) {
perror("recv");
} else {
write(1, buffer, count);
}
}
}
}
}
}
}
}
// while((count = recv(createsocket, buffer, bufsize, 0)) > 0)
// write(1, buffer, count);
printf("EOF.\n");
for(i=0;i<4;i++)
{
close(newsocket[i]);
}
return close(createsocket);
}
- "Scheint nicht zu funktionieren wie erwartet" nicht akzeptabel ist, die Beschreibung des Problems. Mehr Informationen bitte.
- Gut, mit wählen Sie auf dem client die tcp-Verbindung, die ich versuche zu schaffen, eine Reihe von neuen Steckdosen zu recv die Daten der verbundenen tcp-server. Da recv ist ein blockierendes Protokoll bin ich Gebrauch machen, wählen Sie(..) an recv die Daten vom server auf verschiedenen neu erstellten sockets auf der client-Seite. Sind die Dinge ein wenig klar?
- Der client erstellt k TCP-sockets (für jeweils einen chunk zu erhalten, die in teilen) und benutzt "select (...)" - Funktion für asynchrone IO. Das heißt, der client lädt die chunks die parallel und nutzt IO-multiplexing statt multi-threading. Wenn alle chunks empfangen es einfach verschmilzt die Teile in eine einzige Datei.
- Für den Start vielleicht wäre es eine gute Idee, versuchen zu bekommen, wählen Sie arbeiten mit nur ein Buchse.
- Ich begann mit einer Steckdose, es funktioniert. Ich merke, dass die anderen Steckdosen, die ich erstellt baumeln & nicht mit dem server verbunden, in eh. Die eine Steckdose funktioniert, wie es bereits mit dem server verbunden, auf eine tcp-Verbindung. Eine Möglichkeit, dass ich verbinden Sie die Steckerleisten vom client zum gleichen server?
- recv() nicht ein Protokoll ist TCP; TCP ist nicht eine blockierende Protokoll; recv() ist ein Systemaufruf, und es heißt auf einem sockel, das ist der Endpunkt einer Verbindung, und die non-blocking-Modus: nicht, dass Sie wirklich tun müssen, dass für recv() bei der Verwendung von select().
- Zu verbinden, ein socket zu einem server verwenden
connect()
zu einem Gründen weiteres - Verbindung. - Ich habe verwendet, connect( ), habe ich viele änderungen vorgenommen hat, nachdem das auch. Weiß nicht, was das problem ist. Ich poste den code in der Antwort-Abschnitt
- Die OP ' s Quelle zeigen genau ein Aufruf
connect()
. Dies gibt Ihnen genau ein - Verbindung. Die haben mehr verbindungen nennenconnect
mehr oft.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Zwei kurze Bemerkungen:
Ersten, die wir brauchen würden, um den Datei-Deskriptor (fd) -- wie viele fds, wie die Anwendungslogik Anforderungen -- vor dem Aufruf von select() jedes mal in der while-Schleife. Wir sollten auch festlegen, fd_set zu Nullen, bevor Sie den obigen Schritt. Dies ist, weil, wenn select zurückkehrt, wird es wieder die gleichen fd_set aber es wird nur diejenigen, die die Veranstaltung eingestellt. Also, ein Weg dies zu tun ist zu beginnen mit einer sauberen Zustand und legen Sie dann alle fds, die wir interessiert sind. So etwas wie dieses:
Zweite, die Sie erstellen, alle anderen Steckdosen (neben socket createsocket) öffnet einen TCP-socket und noch nichts zu tun mit Ihr. Wenn es ein client, zumindest würden wir dem Aufruf von connect(). Ohne den Aufbau einer expliziten Verbindung, können wir nicht tun, etwas sinnvolles mit TCP-sockets.
So, high-level-Kommentar ist, dass, wenn Sie wollen, haben N client-sockets, öffnen N-buchsen, und schließen Sie alle sockets auf den server. Als Nächstes gehe durch alle N-fds-auf die select() (jedes mal, wenn Sie anrufen wählen Sie()) und tun dies in einer Schleife.
Das problem ist, dass Sie anrufen
recv()
auf Steckdosen, die nicht bereit sind, für das Lesen. Das ist es, wasselect()
ist für, Ihnen zu sagen, welche Steckdosen sind bereit zum Lesen. Ihre Logik, dass Anruferecv()
Prozesse, die die gesamte Sammlung von fds, nicht nur der fds-in den bereit-stellen.