Tanlash uchun ()

Linux/soket dasturlash uchun juda yangi. Men server dasturidagi ulanishlarni tekshirish uchun tanlash dan foydalanaman (oxir-oqibat, suhbat xonasi serveriga aylanadi). Men uni sinovdan o'tkazish uchun telnetdan foydalanmoqdaman va g'alati narsalar sodir bo'layapti. Telnet (telnet localhost 5794) birinchi marta ishga tushirganimda tanlash 1 qaytarsa ​​va mening asosiy fayl identifikatorlari ro'yxatiga yangi ulanishni qo'shib qo'yadi. Hamma narsa yaxshi ko'rinadi.

Ammo keyin telnet-da narsalarni yozishga harakat qilaman va hech narsa bo'lmaydi. Yangi telnet sessiyasini ochmagunimcha, qaytib 0 ni tanlang.

Yangi ulanishlarni topish uchun tanlash kerakmi? Kirishni tekshirish uchun uni ishlatishim mumkin deb o'yladim. Quyida kodimning bir nusxasi (bu so'nggi bir necha soat ichida u bilan aralashtirib yubordim, chunki bu biroz asabiylashdi.

#include "chatpacket.cpp"
#include "serverFunctions.cpp"

#define SERVER_PORT 5794
#define MAX_PENDING 10

int main() {
  fd_set connections;
  fd_set waitingConnections;
  user *clients = new user[50];
  int serverSocket = ServerSetup (SERVER_PORT, MAX_PENDING);
  int maxFD = serverSocket;
  int ConnectionCount;

  struct timeval tv;

  FD_ZERO(&connections);
  FD_SET(0, &connections);
  FD_SET(serverSocket, &connections);

  tv.tv_sec = 1;
  tv.tv_usec = 100;

  bool shutdown = false;
  bool tmpflag = true;
  while(!shutdown) { 

    if (tmpflag == true){printf("in the loop!\n");tmpflag=false;}
    waitingConnections = connections;

    ConnectionCount = select((maxFD+1), &waitingConnections, NULL, NULL, &tv);

    if (ConnectionCount == -1) {
        ///HANDLE ERROR!!!!!!
        printf("Connection Error!");
    }
    else if (ConnectionCount > 0) {
      if (FD_ISSET(serverSocket, &waitingConnections)){
           newConnection(serverSocket, connections, maxFD, clients); //this works fine
      }
      else {
           checkConnections(clients, waitingConnections, maxFD); //the code never gets here
      }
    }

    //check keyboard
    shutdown = checkKeyboard();

  }
}

EDIT: NewConnection uchun kod:

bool newConnection(int serverSocket, fd_set& ConnectionList, int maxFD, user* userGroup){
    printf("in newConnection\n");
    struct sockaddr_storage remoteaddr;

    socklen_t addrlen = sizeof remoteaddr;

    int newFD = accept(serverSocket,(struct sockaddr *)&remoteaddr,&addrlen);
    FD_SET(newFD, &ConnectionList);

    if (newFD > maxFD)
        maxFD = newFD;

    printf("We have a new connection!!! (newConnetcion)\n");

    bool userAdded = false;
    for (int i = 0; i < 50; i++){
      if (userGroup[i].active == false){
            userGroup[i].socket = newFD;
            userGroup[i].active = true;
            userAdded = true;
                        printf("User added in the %ith position of the array.(socket number %i)\n",i,newFD);
            break;
      }
    }
    if (!userAdded)
        printf("new user was not added! (newConnetcion)\n");
}

CheckConnections funktsiyasi boshida printf-ga ega, shuning uchun funktsiyaga kirgan har bir narsani ko'rishim mumkin. Hech qachon chop qilinmaydi.

1
tanlash ni tanlagandan so'ng, accept deb chaqirasiz, to'g'rimi? Va accept tomonidan qaytarilgan soketda read deb chaqirasizmi?
qo'shib qo'ydi muallif Dietrich Epp, manba
read va recv asosan soket uchun bir xil narsa. maxFD har doim ortib bormoqda? Yangi rozetkani fd_setga qo'shasizmi?
qo'shib qo'ydi muallif Dietrich Epp, manba
Finalning 'else' uchun hech qanday sabab yo'q. Siz kiruvchi ma'lumotni bir vaqtning o'zida olishingiz mumkin va .
qo'shib qo'ydi muallif EJP, manba
NewConnect funktsiyasi qabul qiladi va asosiy ro'yxatga qaytarilgan fayl identifikatorini qo'shadi, ammo men uni o'qimaganman ... Hozir buni sinab ko'raman.
qo'shib qo'ydi muallif James - not really a pirate, manba
Yaxshi, men o'qishni qanday qilish kerakligiga ishonchim komil emas. CheckConnections funktsiyasi kirishni olish uchun recv-ni chaqiradi. Buning uchun o'qish kerakmi? Yoki o'qiyman, keyinroq qayta chaqiraman.
qo'shib qo'ydi muallif James - not really a pirate, manba
Ha va ha. Ushbu savolga checkConnections kodini qo'shib qo'ydim. Ehtimol, oddiygina yo'qolgan narsa. Sizning yordamingiz uchun juda minnatdorman.
qo'shib qo'ydi muallif James - not really a pirate, manba

1 javoblar

Mana muammo.

int main(int argc, char *argv[])
{
    int maxFD = ...;
    ...
    newConnection(..., maxFD, ...);
    ...
}

void newConnection(..., int maxFD, ...)
{
    ...
    if (newFD > maxFD)
        maxFD = newFD;
    ...
}

maxFD nomli ikkita parametr mavjud: biri main funktsiyasida va newConnection funktsiyasida. O'zgartirish bir boshqa narsani o'zgartirmaydi. Takliflar: uning o'rniga global foydalaning. (Sababi: Barcha ilovalar uchun faqat bittasi mavjud va unga kirish uchun ko'p funktsiyalar kerak.)

Bu juda muhim xato. Agar siz peshonangizni tiqib olmaysiz va "Dsh oh, bu aniq" deb aytsangiz, unda siz qaytib borib, dasturiy ta'minot kitobiga kirishni qayta ko'rib chiqishingiz mumkin.

1
qo'shib qo'ydi
Sizga katta rahmat!!! Bu butunlay tuzatdi. Siz (yoki ayol) mening qahramonimsiz!
qo'shib qo'ydi muallif James - not really a pirate, manba
Ha. Men befoyda his qilaman.
qo'shib qo'ydi muallif James - not really a pirate, manba