// Send multiple messages. // // If flag bit ZMQ_SNDMORE is set the vector is treated as // a single multi-part message, i.e. the last message has // ZMQ_SNDMORE bit switched off. // int zmq_sendiov (void *s_, iovec *a_, size_t count_, int flags_) { if (!s_ || !((zmq::socket_base_t*) s_)->check_tag ()) { errno = ENOTSOCK; return -1; } int rc = 0; zmq_msg_t msg; zmq::socket_base_t *s = (zmq::socket_base_t *) s_; for (size_t i = 0; i < count_; ++i) { rc = zmq_msg_init_size (&msg, a_[i].iov_len); if (rc != 0) { rc = -1; break; } memcpy (zmq_msg_data (&msg), a_[i].iov_base, a_[i].iov_len); if (i == count_ - 1) flags_ = flags_ & ~ZMQ_SNDMORE; rc = s_sendmsg (s, &msg, flags_); if (unlikely (rc < 0)) { int err = errno; int rc2 = zmq_msg_close (&msg); errno_assert (rc2 == 0); errno = err; rc = -1; break; } } return rc; }
int zmq_msg_send (zmq_msg_t *msg_, void *s_, int flags_) { zmq::socket_base_t *s = as_socket_base_t (s_); if (!s) return -1; return s_sendmsg (s, msg_, flags_); }
int zmq_send (void *s_, const void *buf_, size_t len_, int flags_) { if (!s_ || !((zmq::socket_base_t*) s_)->check_tag ()) { errno = ENOTSOCK; return -1; } zmq_msg_t msg; int rc = zmq_msg_init_size (&msg, len_); if (rc != 0) return -1; memcpy (zmq_msg_data (&msg), buf_, len_); zmq::socket_base_t *s = (zmq::socket_base_t *) s_; rc = s_sendmsg (s, &msg, flags_); if (unlikely (rc < 0)) { int err = errno; int rc2 = zmq_msg_close (&msg); errno_assert (rc2 == 0); errno = err; return -1; } // Note the optimisation here. We don't close the msg object as it is // empty anyway. This may change when implementation of zmq_msg_t changes. return rc; }
int zmq_send (void *s_, const void *buf_, size_t len_, int flags_) { zmq::socket_base_t *s = as_socket_base_t (s_); if (!s) return -1; zmq_msg_t msg; if (zmq_msg_init_size (&msg, len_)) return -1; // We explicitly allow a send from NULL, size zero if (len_) { assert (buf_); memcpy (zmq_msg_data (&msg), buf_, len_); } int rc = s_sendmsg (s, &msg, flags_); if (unlikely (rc < 0)) { int err = errno; int rc2 = zmq_msg_close (&msg); errno_assert (rc2 == 0); errno = err; return -1; } // Note the optimisation here. We don't close the msg object as it is // empty anyway. This may change when implementation of zmq_msg_t changes. return rc; }
void serv_kill_client (serverchan *sc,s_client *al) { s_client *bl; mestyp b; if (al!=NULL) { //Client rausschmei˜en... b=MESEXITSERVER; if (sendto (sc->fd, &b, sizeof(mestyp), 0, (struct sockaddr *) &al->a, sizeof (struct sockaddr)) < 0) { debug_print ("Send Error!\n"); return; } // Aus Liste löschen... #ifdef PAS_RECV s_sendmsg (sc,al,32,2,0,0); #endif if (sc->first==al) sc->first=al->next; else { for (bl=sc->first;bl->next!=al;bl=bl->next); bl->next=al->next; } free (al->buf); free (al); } }
int zmq_msg_send (zmq_msg_t *msg_, void *s_, int flags_) { if (!s_ || !((zmq::socket_base_t*) s_)->check_tag ()) { errno = ENOTSOCK; return -1; } zmq::socket_base_t *s = (zmq::socket_base_t *) s_; int result = s_sendmsg (s, msg_, flags_); return result; }
void __INLINE__ s_decompr_int (serverchan *c,s_client *a,char *buf) { int n,g,arg1,arg2; messheader *h=(messheader *) buf; int *data=(int *) (h+1); n=h->num;g=h->group; arg1=data[0];arg2=data[1]; s_sendmsg (c,a,g,n,arg1,arg2); }
int zmq_send_const (void *s_, const void *buf_, size_t len_, int flags_) { zmq::socket_base_t *s = as_socket_base_t (s_); if (!s) return -1; zmq_msg_t msg; int rc = zmq_msg_init_data (&msg, const_cast<void *> (buf_), len_, NULL, NULL); if (rc != 0) return -1; rc = s_sendmsg (s, &msg, flags_); if (unlikely (rc < 0)) { int err = errno; int rc2 = zmq_msg_close (&msg); errno_assert (rc2 == 0); errno = err; return -1; } // Note the optimisation here. We don't close the msg object as it is // empty anyway. This may change when implementation of zmq_msg_t changes. return rc; }
// Server Main Loop... void calcserv(serverchan *sc) { struct sockaddr_in taddr; sock_size_t addrlength; // I hate these different types in different envs char gbuf[MAXBUF]; int gbuflen,gbufpos,datalen; int i; mestyp b; s_client *al,*bl; // Messages empfangen addrlength=sizeof(struct sockaddr_in); while ((gbuflen=recvfrom (sc->fd, gbuf, MAXBUF, 0, (struct sockaddr *) &taddr, &addrlength)) > 0) { gbufpos=0; // Client suchen for (al=sc->first;al!=NULL;al=al->next) if (al->a.sin_port==taddr.sin_port && al->a.sin_addr.s_addr==taddr.sin_addr.s_addr) break; if (al!=NULL || (*((mestyp *) (gbuf+gbufpos))==MESNEWCLIENT)) { while (gbufpos<gbuflen) { if (al!=NULL && al->status==1) { // Noch Daten erwartet... memcpy (al->buf+al->bufpos,gbuf, (gbuflen-gbufpos)<al->rest ? (gbuflen-gbufpos) : al->rest); if ( (gbuflen-gbufpos) <al->rest) { al->bufpos+=gbuflen-gbufpos; gbufpos=0; } else { switch (al->aktion) { case MT_INTEGER: s_decompr_int (sc,al,al->buf); break; case MT_STRING: s_decompr_str (sc,al,al->buf); break; case MT_DATA: s_decompr_dat (sc,al,al->buf); break; default: debug_print ("seltsamer Fehler!\n"); } al->bufpos=0; al->aktion=0; al->status=0; gbufpos+=al->rest; } } else { // Aktion herausfinden if (al!=NULL && al->status!=0) { b=al->status; } else { b=*((mestyp *) (gbuf+gbufpos)); gbufpos+=sizeof(mestyp); } switch ( b ) { case MESNEWCLIENT: // An Liste anh„ngen... if (al==NULL) { if (sc->acpt_client) { al=sc->first; sc->first= (s_client *) malloc (sizeof(s_client)); sc->first->buf=(char *) malloc(MAXBUF); sc->first->bufpos=0; sc->first->status=0; sc->first->rest=0; sc->first->aktion=0; sc->first->a=taddr; sc->first->next=al; al=sc->first; // Accept Message b=MESACPTCLIENT; if (sendto (sc->fd, &b, sizeof(mestyp), 0, (struct sockaddr *) &taddr, addrlength) < 0) { debug_print ("Send Error!\n"); return; } debug_print ("Client accepted!\n"); #ifdef PAS_RECV s_sendmsg (sc,sc->first,32,1,0,0); #endif } else { //Client rausschmei˜en... b=MESDENYCLIENT; if (sendto (sc->fd, &b, sizeof(mestyp), 0, (struct sockaddr *) &taddr, addrlength) < 0) { debug_print ("Send Error!\n"); return; } debug_print ("Client denied!\n"); } } else debug_print ("Double Accepting!\n"); break; case MESSYNC: debug_print ("Synchronizing... \n"); server_sync(al); break; case MESEXITCLIENT: // Aus Liste l÷schen... debug_print ("Client disconnected!\n"); #ifdef PAS_RECV s_sendmsg (sc,al,32,2,0,0); #endif if (sc->first==al) sc->first=al->next; else { for (bl=sc->first;bl->next!=al;bl=bl->next); bl->next=al->next; } /* Alle vorkommen in der Message-Queue suchen und löschen... */ for (i=0;i<sc->qpos;i++) { if (sc->queue[i]->a==&al->a) sc->queue[i]->a=NULL; } free (al->buf); free (al); al=NULL; break; case MESMESS: //Header lesen... if (gbuflen-gbufpos==0) { al->status=MESMESS; /* Auf Header warten */ } else if (gbuflen-gbufpos < sizeof(messheader)) { /*Schit! Header ist nicht mehr mit im Paket!*/ debug_print ("Header nicht mit im Paket!\n"); server_sync(al); } else { messheader *h=(messheader *) gbuf+gbufpos; if (gbuflen-gbufpos>=sizeof(messheader)+h->len) /* Message passt in einen Buffer, GUT! */ { switch (h->typ) { case MT_INTEGER: s_decompr_int (sc,al,(char *) h); break; case MT_STRING: s_decompr_str (sc,al,(char *) h); break; case MT_DATA: s_decompr_dat (sc,al,(char *) h); break; default: debug_print ("fehlerhafte Message!\n"); server_sync(al); break; } gbufpos+=sizeof(messheader)+h->len; al->status=0; } else { /* Message passt nicht, SCHLECHT! */ al->status=1; al->rest=h->len- (sizeof(messheader)+gbuflen-gbufpos); al->bufpos=gbuflen-gbufpos; al->aktion=h->typ; memcpy (al->buf,h,gbuflen-gbufpos); gbufpos=gbuflen; debug_print ("Big Message!\n"); } } break; default: debug_print ("Unbekannte Message!\n"); server_sync(al); } // case mestyp... } // if status=0 } // While gbufpos>0 } // if al!=NULL || b=MESNEWCLIENT } // while recvfrom... // Queue senden... for (i=0;i<sc->qpos;i++) { if (sc->queue[i]->a!=NULL) { b=MESMESS; if (sendto (sc->fd, &b, sizeof(mestyp), 0, (struct sockaddr *) sc->queue[i]->a, sizeof(struct sockaddr_in)) != sizeof(mestyp)) { debug_print ("Send Fehler!\n"); } datalen=sizeof(messheader)+sc->queue[i]->h.len; if (sendto (sc->fd, &(sc->queue[i]->h), datalen, 0, (struct sockaddr *) sc->queue[i]->a, sizeof(struct sockaddr_in)) != datalen) { debug_print ("Send Fehler!\n"); } free (sc->queue[i]); } } // Queue leeren sc->qpos=0; }