![]() |
| | #1 |
| Registered User Join Date: Jun 2009
Posts: 2
| multi-thread socket program with packet fragmentation Program structure: socket send() is done in main thread when a timer goes off. and in WM_CREATE, I start a thread to listen on the socket and receive in an infinite loop, which is recvThread shown below. Problem: In debugging mode, I can see that each JPEG frame is received correctly when (recvNum == totalNum, set break point here). However, in run-time(or when I set break point in "jpeg_decode(jpegBuf, bmpBuf, pr->bmpFrameSize);"), each JPEG frame has some wrong data and the image is either incomplete or with some wrong part. The following is some related code. I will paste more if necessary. New here, thanks in advance. Code: typedef struct {
int* len;
long* fn;
long* pn;
SOCKET fd;
unsigned char *encBuf;
unsigned char *frameBuf;
unsigned char *outFrameBuf;
struct JpegPacketStruct jpacket;
struct sockaddr_in saddr;
FIFO *fifo;
HWND hwnd;
HANDLE hEvent;
BOOL bContinue;
DWORD bmpFrameSize;
} FrameInfo;
void *
StartThread(int(*func)(void *arg), void *arg, int size) {
DWORD id;
int *argp;
if(size > 0) {
if((argp = malloc(size)) == 0)
return 0;
memcpy(argp, arg, size);
}
return CreateThread(0, STK_SIZE, (LPTHREAD_START_ROUTINE)func, argp, 0, &id);
}
void *recvThread(void *arg) {
BYTE recvBuf[2048];
BYTE bmpBuf[512*1024];
BYTE jpegBuf[64*1024];
BYTE *pjpegbuf = jpegBuf;
BYTE *pbmpBuf = bmpBuf;
int retval;
int recvNum = 0;
long pktNum, totalNum, frameNum;
static long currentNum = 0; //save serial number for current frame
volatile FrameInfo *pr = (FrameInfo *)arg;
JpegPacket jpacket;
BYTE *pbuf;
BYTE *prframebuf = pr->frameBuf;
int saddr_len = sizeof(pr->saddr);
while(1) {
fd_set fds;
struct timeval tv;
int msec = 5000;
FD_ZERO(&fds);
FD_SET(pr->fd, &fds);
tv.tv_sec = msec/1000;
tv.tv_usec = msec%1000*1000;
if(select((pr->fd)+1, &fds, NULL, NULL, &tv) <= 0)
return -2;
memset(recvBuf, 0, sizeof(recvBuf));
//retval = recv(pr->fd, recvBuf, sizeof(jpacket), 0);
retval = recvfrom(pr->fd, recvBuf, sizeof(jpacket), 0, (struct sockaddr *)(&pr->saddr), &saddr_len);
if (retval == SOCKET_ERROR) {
continue;
}
//frame serial number
pbuf = recvBuf;
pbuf += sizeof(jpacket.header.info);
frameNum = getlong(pbuf);
pbuf += sizeof(jpacket.header.frameNum);
//fragment serial number
pktNum = getlong(pbuf);
pbuf += sizeof(jpacket.header.pktNum);
//number of fragments
totalNum = getlong(pbuf);
pbuf += sizeof(jpacket.header.totalNum);
pbuf += sizeof(jpacket.header.len); //now pbuf points to the beginning of img data
//move ptr to correct location according to pktNum and copy data
pjpegbuf = jpegBuf;
pjpegbuf += (pktNum)*sizeof(jpacket.payload);
memcpy(pjpegbuf, pbuf, sizeof(jpacket.payload));
//number of fragments received
recvNum += 1;
if((recvNum == totalNum) || (pktNum == totalNum - 1)) {
jpeg_decode(jpegBuf, bmpBuf, pr->bmpFrameSize);
memcpy(pr->outFrameBuf, bmpBuf, pr->bmpFrameSize);
//write to FIFO
pbmpBuf = bmpBuf;
pbmpBuf += sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
write_fifo(pr->fifo, pbmpBuf);
PostMessage(pr->hwnd, WM_FRAME_RECEIVED, 0, 0);
recvNum = 0;
currentNum ++;
}
}
}
|
| thinkerchjf is offline | |
| | #2 | |||
| Senior software engineer Join Date: Mar 2007 Location: Portland, OR
Posts: 5,357
| This whole segment of code seems pointless, since the call to recvfrom() would block exactly the same way select would: Quote:
Quote:
Quote:
How do you deal with packets that get lost in the network (it happens all the time)?
__________________ "Congratulations on your purchase. To begin using your quantum computer, set the power switch to both off and on simultaneously." -- raftpeople@slashdot | |||
| brewbuck is offline | |
| | #3 |
| Registered User Join Date: Jun 2009
Posts: 2
| Hi brewbuck, thanks for your quick reply. I am really to C, pls excuse my terrible coding. I just want to write a thing that runs correctly first. the out-of-order and loss of packets are serious problems. so I am testing this with a udp server on localhost, is it still common? Thanks. I was dealing with out-of-order fragments in the following code: construct JPEG buffer for one frame with all of its fragments according to the pktNum(serial number of fragment). for each frame, pktNum 0 will be placed at the beginning of the buffer, pktNum 2 at the [2] location, and so forth. Code: //move ptr to correct location according to pktNum and copy data prframebuf = pr->frameBuf; prframebuf += (pktNum)*sizeof(jpacket.payload); memcpy(prframebuf, pbuf, sizeof(jpacket.payload)); Last edited by thinkerchjf; 06-25-2009 at 11:57 AM. Reason: explain something |
| thinkerchjf is offline | |
![]() |
| Thread Tools | |
| Display Modes | |
|
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Program Plan | Programmer_P | C++ Programming | 0 | 05-11-2009 01:42 AM |
| Error with first socket program | JFonseka | C Programming | 1 | 02-03-2008 08:47 PM |
| Global Variables | Taka | C Programming | 34 | 11-02-2007 03:25 AM |
| my server program auto shut down | hanhao | Networking/Device Communication | 1 | 03-13-2004 10:49 PM |
| How to make a thread sleep or std::recv timeout? | BrianK | Linux Programming | 3 | 02-26-2003 10:27 PM |