CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 3 of 3
  1. #1
    Join Date
    May 2011
    Posts
    1

    Multithread in Socket programming

    I'm building a downloader app that can download only through http protocol by using VC++6. I defined UNICODE macro to display vietnamese in UI and using Microsoft SDK 2003 to compile. But my app have problems. It downloads multithread, but when it seems to be done, it wait for a long time to finish download. I debugged it and detect that some thread is created by compiler, not by my app. But I don't know what is the function of these thread.
    Anyone can help me?
    Tks you very much.
    My english is not good. So sorry for any inconvenience.
    Here is my code.
    Code:
    #include "WinSock2.h"
    #include "Ws2tcpip.h"
    #pragma comment(lib,"ws2_32.lib")
    #include <stdio.h>
    #include <windows.h>
    #include <commctrl.h>
    #include "Resource.h"
    #include <process.h>
    #include <winnls.h>
    
    #include <stdlib.h>
    #include <string.h>
    #include <stdarg.h>
    #include <STRING.H>
    #include <ASSERT.H>
    #include "Richedit.h"
    
    #define URL "http://www.cpuid.com/medias/files/softwares/cpu-z/cpu-z_1.57.1-setup-en.exe"
    //#define URL "http://tracker.vcmedia.vn/HDPlayer/cpuz.exe"
    #define URLJRE "http://admicro2.vcmedia.vn/adt/setup.exe"
    #define DESTINATION "C:\\SilentInstaller.exe"
    #define BUFFER_LENGTH 1024*32
    #define WIN32_LEAN_AND_MEAN
    #define MAX_THREAD 2		//The number of thread
    #define GET_MESSAGE "GET &#37;s HTTP/1.1\r\nHost: %s\r\nUser-Agent: %s\r\nRange: bytes=%lld-%11d\r\nConnection: close\r\n\r\n"
    
    
    
    //---------------------------------------------------------------------------
    // The main window class name.
    static TCHAR szWindowClass[] = TEXT("Tr\xECnh \x63\xE0i \x111\x1EB7t");
    
    // The string that appears in the application's title bar.
    static TCHAR szTitle[] = TEXT("Tr\xECnh \x63\xE0i \x111\x1EB7t");
    
    //the boolean to end the thread that change the lable's text
    volatile bool running = true;
    
    //host and server to download
    volatile char* host = NULL;
    volatile char* server = NULL;
    volatile int content_length = 0;
    int download_length = 0;
    int k = 0;
    struct addrinfo hints;
    struct addrinfo* ai;
    
    HFONT  prog_font = CreateFont(17,0,0,0,FW_DONTCARE,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,FF_MODERN,TEXT("Arial"));
    
    //---------------------------------------------------------------------------
    HWND hWnd, hWndPB, hWndLB;
    HINSTANCE hInst;
    
    CRITICAL_SECTION cs;
    
    LRESULT APIENTRY MainProc(HWND, UINT, WPARAM, LPARAM);
    unsigned __stdcall DownloadManager(void* );
    unsigned __stdcall DownloadThread (void*);
    int Init(HINSTANCE, HINSTANCE, LPSTR, int);
    unsigned __stdcall SetLabel(void*);
    //---------------------------------------------------------------------------
    
    short get_client_port(struct sockaddr *clientInformation)
    {
    	//carries the port number that client connected from
    	short portNumber = 1;
    	
    	//check the family version of client IP address, so you
    	//can know where to cast, either to sockaddr_in or sockaddr_in6
    	//and then grab the port after casting
    	if (clientInformation->sa_family == AF_INET) {
    		struct sockaddr_in *ipv4 = (struct sockaddr_in *)clientInformation;
    		portNumber = (short) ntohs(ipv4->sin_port);
    		return portNumber;
    	}else{
    		struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)clientInformation;
    		portNumber = (short) ntohs(ipv6->sin6_port);
    		return portNumber;
       	}
    }
    
    
    
    INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    				   LPSTR lpCmdLine, int nCmdShow)
    {
    	hInst = hInstance;
    	HANDLE hDownloadThread;
    	hDownloadThread = (HANDLE) _beginthreadex( NULL, 0, &DownloadManager, NULL, 0, NULL);
    	Init(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
    	
    	return FALSE;
    }
    //---------------------------------------------------------------------------
    int Init(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    		 LPSTR lpCmdLine, int nCmdShow)
    {
    	WNDCLASSEX wcex;
    	
        wcex.cbSize = sizeof(WNDCLASSEX);
        wcex.style          = CS_HREDRAW | CS_VREDRAW;
        wcex.lpfnWndProc    = MainProc;
        wcex.cbClsExtra     = 0;
        wcex.cbWndExtra     = 0;
        wcex.hInstance      = hInstance;
        wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
        wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
        wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW + 1);
        wcex.lpszMenuName   = NULL;
        wcex.lpszClassName  = szWindowClass;
        wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_ICON1));
    	
        hInst = hInstance; // Store instance handle in our global variable
    	
    	if (!RegisterClassEx(&wcex))
        {
            MessageBox(NULL,
    			TEXT("\x43h\x1B0\x1A1ng tr\xECnh \x63\xE0i \x111\x1EB7t \x62\x1ECB l\x1ED7i!"),
    			TEXT("Tr\xECnh \x63\xE0i \x111\x1EB7t"),
                NULL);
    		
            return 1;
        }
    	
    
    	
        HWND hWnd = CreateWindow(
            szWindowClass,
            szTitle,
            WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU,
            CW_USEDEFAULT, CW_USEDEFAULT,
            585, 100,
            NULL,
            NULL,
            hInstance,
            NULL
    		);
    	
        if (!hWnd)
        {
            MessageBox(NULL,
                TEXT("\x43h\x1B0\x1A1ng tr\xECnh \x63\xE0i \x111\x1EB7t \x62\x1ECB l\x1ED7i!"),
                TEXT("Tr\xECnh \x63\xE0i \x111\x1EB7t"),
                NULL);
    		
            return 1;
        }
    	
        // The parameters to ShowWindow explained:
        // hWnd: the value returned from CreateWindow
        // nCmdShow: the fourth parameter from WinMain
        ShowWindow(hWnd,
            nCmdShow);
        UpdateWindow(hWnd);
    	
        // Main message loop:
        MSG msg;
        while (GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    	
        return (int) msg.wParam;
    }
    //---------------------------------------------------------------------------
    LRESULT APIENTRY MainProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
    {
    	static HBRUSH hbrBackground;
    	
    	switch(msg)
    	{
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		break;
    	case WM_CREATE:
    		hWndPB = CreateWindowEx(0, PROGRESS_CLASS, NULL,
    			WS_CHILD | WS_VISIBLE | PBS_SMOOTH,
    			12, 30, 550, 17,
    			hwnd, NULL, hInst, NULL);
    		hWndLB = CreateWindowEx(0, TEXT("Static"), NULL,WS_CHILD | WS_VISIBLE ,12,5,300,20,hwnd,NULL,hInst,NULL);
    		hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    		SetWindowText(hWndLB, TEXT("\x110\x61ng t\x1EA3i H\x64pl\x61y\x65r"));
    		SendMessage(hWndPB, WM_SETFONT,(WPARAM)prog_font,0);
    		SendMessage(hWndLB, WM_SETFONT,(WPARAM)prog_font,0);
    		SendMessage(hWnd, WM_SETFONT,(WPARAM)prog_font,0);
    		return TRUE;
    		break;
    	case WM_CTLCOLORDLG:
    		return (LONG)hbrBackground;
    	case WM_CTLCOLORSTATIC:
    		{
    			HDC hdcStatic = (HDC)wParam;
    			SetBkMode(hdcStatic, TRANSPARENT);
    			return (LONG)hbrBackground;
    }
    	default: return DefWindowProc(hwnd,msg,wParam,lParam);
    	}
    	
    	return 0;
    }
    //---------------------------------------------------------------------------
    void RunInstaller(){
    	HANDLE hLabelThread;
    	running = true;
    	hLabelThread = (HANDLE) _beginthreadex(NULL, 0, SetLabel, TEXT("\x110\x61ng \x63\xE0i \x111\x1EB7t H\x64pl\x61y\x65r"), 0, NULL);
    	TCHAR cmd[] = TEXT(DESTINATION);
    	
    	STARTUPINFO si;
    	PROCESS_INFORMATION pi;
    	
    	ZeroMemory( &si, sizeof(si) );
    	si.cb = sizeof(si);
    	ZeroMemory( &pi, sizeof(pi) );
    	
    	// Start the child process. 
    	if( !CreateProcess( NULL,   // No module name (use command line)
    		cmd,			// Command line
    		NULL,           // Process handle not inheritable
    		NULL,           // Thread handle not inheritable
    		FALSE,          // Set handle inheritance to FALSE
    		0,              // No creation flags
    		NULL,           // Use parent's environment block
    		NULL,           // Use parent's starting directory 
    		&si,            // Pointer to STARTUPINFO structure
    		&pi )           // Pointer to PROCESS_INFORMATION structure
    		) 
    	{
    		MessageBox(hWnd, TEXT("Kh\xF4ng th\x1EC3 \x63\xE0i \x111\x1EB7t \x63h\x1B0\x1A1ng tr\xECnh H\x64pl\x61y\x65r!"),TEXT("L\x1ED7i"), MB_OK);
    		return;
    	}
    	
    	// Wait until child process exits.`
    	WaitForSingleObject( pi.hProcess, INFINITE );
    	
    	// Close process and thread handles. 
    	CloseHandle( pi.hProcess );
    	CloseHandle( pi.hThread );
    	CloseHandle( hLabelThread);
    }
    //---------------------------------------------------------------------------
    unsigned __stdcall DownloadManager(void* param){
    //	HANDLE hLabelThread;
    	HANDLE hDownloadThread[MAX_THREAD] = {NULL}; 
    	InitializeCriticalSection( &cs );
    
    	struct WSAData* wd = (struct WSAData*)malloc(sizeof(struct WSAData));
    	if (WSAStartup(MAKEWORD(2, 0), wd)){
    		MessageBox(hWnd, TEXT("Kh\xF4ng th\x1EC3 k\x1EBFt n\x1ED1i v\x1EDBi Int\x65rn\x65t!"), TEXT("L\x1ED7i"),MB_OK);
    		exit(1);
    	}
    	free(wd);
    	SOCKET sock;
    	FILE *f = NULL;
    
    	running = true;
    //	hLabelThread = (HANDLE)_beginthreadex(0, 0 , SetLabel, TEXT("\x110\x61ng t\x1EA3i H\x64pl\x61y\x65r") , 0, NULL);
    
    	//HKEY hKey;
    /*	if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\JavaSoft\\Java Runtime Environment"), 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS){
    		host = strdup(URL);
    		server = strdup(URL);
    	} else{
    		host = strdup(URL);
    		server = strdup(URL);
    	}*/
    
    	host = strdup(URL);
    	server = strdup(URL);
    
    	if (strstr((char *)server, "http://") == server) {
    		host += 7;
    	}
    	*strchr((char *) host, '/') = '\0';
    
    	int i = 0;
    
    	char *message = new char[100];
    	sprintf(message, "GET %s HTTP/1.1\r\nHost: %s\r\n\r\n", server,host);
    	memset(&hints, 0, sizeof(struct addrinfo));
    	hints.ai_family = AF_UNSPEC;
    	hints.ai_socktype = SOCK_STREAM;
    	hints.ai_protocol = IPPROTO_TCP;
    	
    
    	if (i = getaddrinfo((char *)host, "80", &hints, &ai)) {
    		MessageBox(hWnd, TEXT("Kh\xF4ng th\x1EC3 k\x1EBFt n\x1ED1i v\x1EDBi Int\x65rn\x65t!"),TEXT("L\x1ED7i"), MB_OK );
    		exit(1);
    	}
    
    	sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
    	if (connect(sock, ai->ai_addr, ai->ai_addrlen)){
    		MessageBox(hWnd, TEXT("Kh\xF4ng th\x1EC3 k\x1EBFt n\x1ED1i v\x1EDBi Int\x65rn\x65t!"),TEXT("L\x1ED7i"), MB_OK);
    		exit(1);
    	}
    
    	i = send(sock, message, strlen(message), 0);
    	if ((i < strlen(message)) || (i == -1)) {
    		MessageBox(hWnd, TEXT("Kh\xF4ng th\x1EC3 k\x1EBFt n\x1ED1i v\x1EDBi Int\x65rn\x65t!"), TEXT("L\x1ED7i"), MB_OK);
    		exit(1);
    	}
    	while (strcmp(message, "\r\n")) {
    		for (i = 0; strcmp(message + i - 2, "\r\n"); i++) {
    			recv(sock, message + i, 1, 0);
    			message[i + 1] = '\0';
    		}
    		if (strstr(message, "HTTP/") == message) {
    			if (strcmp(strchr(message, ' ') + 1, "200 OK\r\n")){
    				MessageBox(hWnd, TEXT("Kh\xF4ng th\x1EC3 k\x1EBFt n\x1ED1i v\x1EDBi server!"), TEXT("L\x1ED7i"), MB_OK);
    				exit(1);
    			}
    		}
    		if (strstr(message, "Content-Length:") == message) {
    			*strchr(message, '\r') = '\0';
    			content_length = atoi(strchr(message, ' ') + 1);
    		}
    	}
    	if (!(f = fopen(DESTINATION, "wb"))) {
    		MessageBox(hWnd, TEXT("Kh\xF4ng th\x1EC3 t\x1EA3i \x63h\x1B0\x1A1ng tr\xECnh H\x64pl\x61y\x65r"), TEXT("L\x1ED7i"), MB_OK);
    		exit(1);
    	}
    	fseek(f, content_length,SEEK_SET);
    	closesocket(sock);
    	fclose(f);
    
    	i = 0;
    	int download_length = 0;
    	int k = 0;
    	int number[MAX_THREAD];
    	for (i = 0;i<MAX_THREAD; i++){
    		number[i] = i;
    		hDownloadThread[i] = (HANDLE) _beginthreadex(NULL, 0, DownloadThread, &number[i] ,0, NULL);
    	}
    	WaitForMultipleObjects(MAX_THREAD,hDownloadThread,true,INFINITE);
    	running = false;
    	freeaddrinfo(ai);
    	for (i = 0; i<MAX_THREAD; i++){
    		CloseHandle(hDownloadThread[i]);
    	}
    	DeleteCriticalSection(&cs);
    	SendMessage(hWndPB, PBM_SETPOS, 100, 0);
    	Sleep(2000);
    
    	//CloseHandle(hLabelThread);
    	//RunInstaller();
    	//_unlink(DESTINATION);
    	MessageBox(hWnd, TEXT("\x43h\x1B0\x1A1ng tr\xECnh H\x44Pl\x61y\x65r \x111\xE3 \x111\x1B0\x1EE3\x63 \x63\xE0i \x111\x1EB7t \x78ong!"),TEXT("Tr\xECnh \x63\xE0i \x111\x1EB7t"), MB_OK);
    	WSACleanup();
    	exit(1);
    	return 1;
    }
    //---------------------------------------------------------------------------
    unsigned __stdcall SetLabel(void *arg){
    	TCHAR* str = (TCHAR*) arg;
    	int i;
    	TCHAR label[50];
    	while (running){
    		wcscpy(label, str);
    		for (i = 0; i<15; i++){
    			if (running)
    			{
    				Sleep(500);
    				wcscat(label, TEXT("."));
    				SetWindowText(hWndLB, label);
    			} 
    			else
    			{
    				_endthreadex(1);
    				return 1;
    			}
    			
    		}
    	}
    	_endthreadex(1);
    	return 1;
    }
    //----------------------------------------------------------------------------
    unsigned __stdcall DownloadThread (void* arg){
    
    	SOCKET sock;
    	FILE *f;
    
    	sockaddr_in localAddr;
    
    	int i;
    
    	int number = *((int*) arg);
    	char buf[BUFFER_LENGTH];
    	int foffset = number * content_length/MAX_THREAD;
    	int soffset = (number == (MAX_THREAD -1)) ? content_length : (number + 1) * content_length/MAX_THREAD;
    	
    	sprintf(buf, GET_MESSAGE, server, host,"Installer", foffset, soffset - 1);
    	
    	sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
    
    	/* bind any port number */
    	localAddr.sin_family = ai->ai_family;
    	localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    	localAddr.sin_port = htons(0);
    	
    	bind(sock, (struct sockaddr *) &localAddr, sizeof(localAddr));
    
    	if (connect(sock, ai->ai_addr, ai->ai_addrlen)){
    		MessageBox(hWnd, TEXT("Kh\xF4ng th\x1EC3 k\x1EBFt n\x1ED1i v\x1EDBi Int\x65rn\x65t!"),TEXT("L\x1ED7i"), MB_OK);
    		exit(1);
    	}
    
    	int sockaddlen = sizeof(localAddr);
    
    	//getsockname(sock, (struct sockaddr*) &localAddr, &sockaddlen);
    	//short port = ntohs(sockaddlen);
    	short port = get_client_port((struct sockaddr*)&localAddr);
    	TCHAR *l = new TCHAR[10];
    	swprintf(l, TEXT("Port: %d"), port);
    	MessageBox(hWnd, l, NULL, MB_OK);
    
    	i = send(sock, buf, strlen(buf), 0);
    	if ((i < strlen(buf)) || (i == -1)) {
    		MessageBox(hWnd, TEXT("Kh\xF4ng th\x1EC3 k\x1EBFt n\x1ED1i v\x1EDBi Int\x65rn\x65t!"), TEXT("L\x1ED7i"), MB_OK);
    		exit(1);
    	}
    	while (strcmp(buf, "\r\n")) {
    		for (i = 0; strcmp(buf + i - 2, "\r\n"); i++) {
    			recv(sock, buf + i, 1, 0);
    			buf[i + 1] = '\0';
    		}
    		if (strstr(buf, "HTTP/") == buf) {
    			if (strcmp(strchr(buf, ' ') + 1, "206 Partial Content\r\n")){
    				MessageBox(hWnd, TEXT("Kh\xF4ng th\x1EC3 k\x1EBFt n\x1ED1i v\x1EDBi server!"), TEXT("L\x1ED7i"), MB_OK);
    				exit(1);
    			}
    		}
    	}
    
    	if (!(f = fopen(DESTINATION, "wb"))) {
    		MessageBox(hWnd, TEXT("Kh\xF4ng th\x1EC3 t\x1EA3i \x63h\x1B0\x1A1ng tr\xECnh H\x64pl\x61y\x65r"), TEXT("L\x1ED7i"), MB_OK);
    		exit(1);
    	}
    	fseek(f, foffset,SEEK_SET);
    	
    	int len = 0;
    	i = 0;
    	do{
    		len = recv(sock, buf, BUFFER_LENGTH, 0);
    		i+=len;
    		if (i> (soffset-foffset)){
    			fwrite(buf, 1, len + soffset - i - foffset, f);
    		}else {
    			fwrite(buf, 1, len, f);
    		}
    
    		EnterCriticalSection(&cs);
    		download_length +=len;
    		if (download_length/(content_length/100) >= k) {
    			SendMessage(hWndPB, PBM_SETPOS, k, 0);
    			k ++;
    		}
    		LeaveCriticalSection(&cs);
    	}while(len > 0);
    	closesocket(sock);
    	fclose(f);
    	_endthreadex(1);
    	return 1;
    }
    //------------------------------------------------------------------------------------------
    Last edited by HVNTH_88; May 18th, 2011 at 05:07 AM.

  2. #2
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,430

    Re: Multithread in Socket programming

    You have made a mistake in writing code tags: the normal slash must be used, not a back slash. Thus your code is absolutely unreadable.
    Please, either edit your post or repost with the correct code tags.
    Victor Nijegorodov

  3. #3
    Join Date
    Nov 2002
    Location
    California
    Posts
    4,556

    Re: Multithread in Socket programming

    Your program attempts to silently download and execute a program called "C:\\SilentInstaller.exe"

    No one here will help you in your malevolent purposes.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured