?? client.c
字號:
/* client.c -- main client source code * * This file is part of 'netcast' program, released under BSD License. * (c) 2001-2002 Stanis砤w Pa秌o <staszek@nutki.com>. All rights reserved. */#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <sys/types.h>#include <sys/socket.h>#include <arpa/inet.h>#include "mdist.h"#include "mdtcp.h"#include "mcast.h"#include "util.h"int main(int argc, char *argv[]) { int ms,ts; /* multicast/tcp sockets */ struct mdmsg *pkt,*tmp; /* receive buffers */ int i,c,r,z; /* counters */ uint32_t l; /* repeat block num */ fd_set rfds; /* 4 select */ struct timeval tv; long rep=0,tot=0; /* stats */ long long size=0; uint8_t byt; /* single-byte messages */ u_short port=0; /* server port */ struct mdreq *req; /* request head */ uint32_t *rqb; /* request body */ char rqbuf[sizeof(struct mdreq)+ROUND*sizeof(uint32_t)]; /* request - buf*/ if (argc<2) { printf("Usage: client IP [port]\n"); return 0; } if (argc>2) port=atoi(argv[2]); /* Connect to server, get multicast group & port, open multicast socket */ ts = mdtcp_open_client(argv[1],port); md_init(); if (read_all(ts,&mdini,sizeof(struct mdinit))!=sizeof(struct mdinit)) ERROR("error while reading initial data"); ms = init_mcast_socket(&mdini.group); /* set_nonblock(ms); */ /* Init buffers */ pkt = (struct mdmsg *) malloc(MMSIZE); req=(struct mdreq *) rqbuf; rqb=(uint32_t *) (rqbuf+sizeof(struct mdreq)); tmp = pkt; i = ts; if (i<ms) i=ms; i++; FD_ZERO(&rfds); do { /* Start a segment */ if (read_all(ts,&mdhead,sizeof(struct mdctl))<sizeof(struct mdctl)) ERROR("Error reading segment header"); byt=CLIENT_READY; write(ts,&byt,1); c=0; z=1; if (mdhead.pkt) do { /* Read packets from multicast and check tcp for end mark */ FD_SET(ts,&rfds);FD_SET(ms,&rfds); tv.tv_sec=6;tv.tv_usec=0; if ((r=select(i,&rfds,0,0,&tv))<0) ERROR("select error"); if (r>0) { /* Read multicast packet */ if (FD_ISSET(ms,&rfds)) { if (tmp) pkt = tmp; r=recv(ms,pkt,MMSIZE,0); if (r<=0) ERROR("error on multicast socket"); if (r<sizeof(struct mdmsg) ) { MSG(7,"Truncated packet received (%d bytes)",r); } else { if (r!=pkt->siz+sizeof(struct mdmsg)) { MSG(7,"Truncated packet received (%d of %d bytes)",r,pkt->siz+sizeof(struct mdmsg)); } else { tmp = md_put(pkt); if (!tmp) MSG(5,"Malformed packet"); if (tmp && !tmp->siz) c++; } } /* Check tcp, only if there was no data on multicast - there may be more */ } else if (FD_ISSET(ts,&rfds)) { /* no more data */ MSG(6,"No more data"); if (read(ts,&byt,1)<1) ERROR("Error on TCP synchronization"); r=0;z=0; } } } while (r>0 && c<mdhead.pkt); if (c==mdhead.pkt) MSG(6,"All packets received"); if (z && read(ts,&byt,1)<1) ERROR("Error on TCP synchronization"); req->ack=mdhead.blk; req->rqc=0; /* Construct request */ if (c<mdhead.pkt) { for (l=0;l<mdhead.pkt;l++) if (!mdbuf[l]->siz) { MSG(6,"Requesting packet %u",l+mdhead.base); rqb[req->rqc]=l+mdhead.base; req->rqc++; } } /* Send request */ if (req->rqc>0) { byt=CLIENT_REQ; write(ts,&byt,1); write(ts,req,sizeof(struct mdreq)+(req->rqc)*sizeof(uint32_t)); /* read repeated blocks via TCP */ for (l=0;l<req->rqc;l++) { if (tmp) pkt = tmp; r=read_all(ts,pkt,sizeof(struct mdmsg)); if (r!=sizeof(struct mdmsg)) ERROR("Error on tcp socket"); r=read_all(ts,((char *) pkt )+sizeof(struct mdmsg),pkt->siz); if (r!=pkt->siz) ERROR("Error on tcp socket received %d of %d",r,pkt->siz); tmp = md_put(pkt); if (!tmp) ERROR("Malformed packet on tcp socket"); MSG(6,"Received packet %u",pkt->seq); } rep+=req->rqc; } tot+=mdhead.pkt;size+=mdhead.siz;// MSG(4,"Received segment: %d bytes in %d packets",mdhead.siz,mdhead.pkt); fprintf(stderr,"\rnetcast: received %lld bytes in %ld packets %ld repeats",size,tot,rep); /* Write data to stdout */ if (mdhead.pkt) md_flush(1); byt=CLIENT_START; write(ts,&byt,1); } while (mdhead.pkt); shutdown(ts,2); fprintf(stderr,"\nnetcast: done.\n");// MSG(4,"Total %ld packets %ld repeated",tot,rep); return 0;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -