Tải bản đầy đủ (.pdf) (33 trang)

BÁO cáo đồ án CHAT CLIENTS SERVER

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (1.15 MB, 33 trang )

Họ và tên: Phạm Vũ Thoại
MSSV: 0971060
Lớp: 09TC – Môn Lập trình mạng

BÁO CÁO ĐỒ ÁN
CHAT CLIENTS-SERVER
NHỮNG VẤN ĐỀ CƠ BẢN VỀ MẠNG
1. Mạng máy tính
Mạng máy tính là tập hợp các máy tính hoặc các thiết bị được nối với
nhau bởi các đường truyền vật lý và theo một kiến trúc nào đó.
Chúng ta có thể phân loại mạng theo qui mô của nó:
 Mạng LAN (Local Area Network)-mạng cục bộ: kết nối các nút trên một
phạm vi giới hạn. Phạm vi này có thể là một công ty, hay một tòa nhà.
 Mạng WAN (Wide Area Network): nhiều mạng LAN kết nối với nhau tạo
thành mạng WAN.
 MAN (Metropolitan Area Network), tương tự như WAN, nó cũng kết nối
nhiều mạng LAN. Tuy nhiên, một mạng MAN có phạm vi là một thành
phố hay một đô thị nhỏ. MAN sử dụng các mạng tốc độ cao để kết nối
các mạng LAN của trường học, chính phủ, công ty, ..., bằng cách sử
dụng các liên kết nhanh tới từng điểm như cáp quang.
1.1

Thiết bị giao tiếp mạng (Network Interface Thiết bị)

NIC là thiết bị giao tiếp được sử dụng để kết nối một thiết bị với mạng
LAN. Nó cho phép chúng ta gửi và nhận các thông điệp từ mạng. Một NIC có
một địa chỉ MAC duy nhất mà cung cấp định danh duy nhất cho từng thiết bị.
Địa chỉ MAC là một số 12 byte-hệ 16 được gán cho thiết bị mạng. Địa
chỉ này có thể được thay đổi bởi một trình điều khiển mạng một cách linh hoạt
(như trong trường hợp của hệ thống DECnet, mạng được phát triển bởi
Digital Equipment), nhưng thông thường địa chỉ MAC không thay đổi.



 
Đồ án môn học Lập trình mạng SV: Phạm Vũ Thoại – 09TC 
 

Trang: 1 


2. Mô hình Client-Server
2.1 Giới thiệu
Mô hình Client/Server là mô hình tổ chức trao đổi thông tin trong đó mô tả
cách mà các máy tính có thể giao tiếp với nhau theo một phương thức nhất
định. Phương thức này là một chiến lược tổ chức phân cấp mà trong đó có
một máy tính đặc biệt phục vụ các yêu cầu về lưu trữ, xử lý, tính toán tất cả
các máy trên mạng. Kiểu tổ chức tổng quát của mô hình này là một mạng
LAN được thiết lập từ nhiều máy tính khác nhau, trong đó một máy tính gọi là
Server. Một chương trình client chạy từ bất kỳ máy tính nào trong mạng cũng
có thể gởi yêu cầu của mình đến Server, khi server nhận được các yêu cầu
này thì nó sẽ thực hiện và gởi kết quả về cho Client.

Hình. Mô hình Client/Server
Có nhiều mô hình được sử dụng trong các chương trình mạng nhưng mô
hình Client/Server là mô hình chuẩn. Một Server là một quá trình, quá trình
này chờ sự liên hệ từ một Client. Một phiên làm việc điển hình của mô hình
này như sau:
-

Phía Client gởi một yêu cầu thông qua mạng đến Server để yêu cầu
một số dạng dịch vụ nào đó như lấy tên máy Server, lấy đồng hồ hệ
thống, đăng ký cấp bằng …


-

Phía Server được khởi động trước trên hệ thống máy tính. Sau khi khởi
động nó sẽ chờ Client liên hệ nó để yêu cầu một số dịch vụ. Quá trình
của Server thành chia ra 2 kiểu:
 Khi chỉ có một yêu cầu của Client được Server phục vụ tại một thời
điểm thì gọi đó là Server lặp.
 Khi Server có thể phục vụ đồng thời nhiều yêu cầu từ Client gởi đến
gọi đó là Server đồng thời.

Client/Server là mô hình tổng quát nhất, trên thực tế thì một Server có thể
được nối tới nhiều Server khác nhằm làm việc hiệu quả hơn. Khi nhận được
một yêu cầu từ Client, Server này có thể gửi tiếp yêu cầu vừa nhận được cho
Server khác ví dụ như Database Server vì bản thân nó không thể xử lý yêu

 
Đồ án môn học Lập trình mạng SV: Phạm Vũ Thoại – 09TC 
 

Trang: 2 


cầu này được. Máy Server có thể thi hành các nhiệm vụ đơn giản hoặc phức
tạp.
Ví dụ như một máy chủ trả lời thời gian hiện tại trong ngày, khi một máy
Client yêu cầu lấy thông tin về thời gian nó sẽ phải gửi một yêu cầu theo một
tiêu chuẩn do Server định ra, nếu yêu cầu được chấp nhận thì máy Server sẽ
trả về thông tin mà Client yêu cầu. Có rất nhiều các dịch vụ Server trên mạng
nhưng nó đều hoạt động theo nguyên lý là nhận các yêu cầu từ Client sau đó

xử lý và trả kết quả cho client yêu cầu. Thông thường chương trình Server và
Client được thi hành trên hai máy khác nhau. Cho dù lúc nào Server cũng ở
trạng thái sẵn sàng chờ nhận yêu cầu từ Client nhưng trên thực tế một tiến
trình liên tác qua lại (interaction) giữa Client và Server lại bắt đầu ở phía
Client, khi mà Client gửi tín hiệu yêu cầu tới Server. Các chương trình Server
thường đều thi hành ở mức ứng dụng (tầng ứng dụng của mạng).
Sự thuận lợi của phương pháp này là nó có thể làm việc trên bất cứ một
mạng máy tính nào có hỗ trợ giao thức truyền thông chuẩn cụ thể ở đây là
giao thức TCP/IP. Với các giao thức chuẩn này cũng giúp cho các nhà sản
xuất có thể tích hợp nhiều sản phẩm khác nhau của họ lên mạng mà không
gặp phải khó khăn gì. Với các chuẩn này thì các chương trình Server cho một
dịch vụ nào đấy có thể thi hành trên một hệ thống chia sẻ thời gian
(timesharing system) với nhiều chương trình và dịch vụ khác hoặc nó có thể
chạy trên chính một máy tính các nhân bình thường. Có thể có nhiều chương
Server cùng làm một dịch vụ, chúng có thể nằm trên nhiều máy tính hoặc một
máy tính.
2.2. Client
Trong mô hình Client/Server, người ta còn định nghĩa cụ thể cho một máy
Client là một máy trạm mà chỉ được sử dụng bởi một người dùng với để
muốn thể hiện tính độc lập cho nó. Máy Client có thể sử dụng các hệ điều
hành bình thường như Win9x, DOS, OS/2...
Bản thân mỗi một Client cũng đã được tích hợp nhiều chức năng trên hệ
điều hành mà nó chạy, nhưng khi được nối vào một mạng LAN, WAN theo
mô hình Client/Server thì nó còn có thể sử dụng thêm các chức năng do hệ
điều hành mạng cung cấp với nhiều dịch vụ khác nhau (cụ thể là các dịch vụ
do các Server trên mạng này cung cấp), ví dụ như nó có thể yêu cầu lấy dữ
liệu từ một Server hay gửi dữ liệu lên Server đó... Thực tế trong các ứng dụng
của mô hình Client/Server, các chức năng hoạt động chính là sự kết hợp giữa
Client và Server với sự chia sẻ tài nguyên, dữ liệu trên cả hai máy.
 

Đồ án môn học Lập trình mạng SV: Phạm Vũ Thoại – 09TC 
 

Trang: 3 


Trong mô hình Client/Server, Client được coi như là người sử dụng các
dịch vụ trên mạng do một hoặc nhiều máy chủ cung cấp và Server được coi
như là người cung cấp dịch vụ để trả lời các yêu cầu của các Clients. Điều
quan trọng là phải hiểu được vai trò hoạt động của nó trong một mô hình cụ
thể, một máy Client trong mô hình này lại có thể là Server trong một mô hình
khác. Ví dụ cụ thể như một máy trạm làm việc như một Client bình thường
trong mạng LAN nhưng đồng thời nó có thể đóng vai trò như một máy in chủ
(printer server) cung cấp dịch vụ in ấn từ xa cho nhiều người khác (Clients)
sử dụng. Client được hiểu như là bề nổi của các dịch vụ trên mạng, nếu có
thông tin vào hoặc ra thì chúng sẽ được hiển thị trên máy Client.
2.3. Server
Server còn được định nghĩa như là một máy tính nhiều người sử dụng
(multiuser computer). Vì một Server phải quản lý nhiều yêu cầu từ các Client
trên mạng cho nên nó hoạt động sẽ tốt hơn nếu hệ điều hành của nó là đa
nhiệm với các tính năng hoạt động độc lập song song với nhau như hệ điều
hành UNIX, WINDOWS... Server cung cấp và điều khiển các tiến trình truy
cập vào tài nguyên của hệ thống.
Các ứng dụng chạy trên Server phải được tách rời nhau để một lỗi của
ứng dụng này không làm hỏng ứng dụng khác. Tính đa nhiệm đảm bảo một
tiến trình không sử dụng toàn bộ tài nguyên hệ thống. Server như là một nhà
cung cấp dịch vụ cho các Clients yêu cầu tới khi cần, các dịch vụ như cơ sở
dữ liệu, in ấn, truyền file, hệ thống... Các ứng dụng Server cung cấp các dịch
vụ mang tính chức năng để hỗ trợ cho các hoạt động trên các máy Clients có
hiệu quả hơn.


 
Đồ án môn học Lập trình mạng SV: Phạm Vũ Thoại – 09TC 
 

Trang: 4 


3. Mô hình Client-Server và các cơ chế chung

Cớ chế chung: Kết nối và gửi, nhận message

 
Đồ án môn học Lập trình mạng SV: Phạm Vũ Thoại – 09TC 
 

Trang: 5 


Mô hình

 
Đồ án môn học Lập trình mạng SV: Phạm Vũ Thoại – 09TC 
 

Trang: 6 


4. Chương trình Server - Clients
4.1. Viết chương trình cho phía máy Server

 Tạo một Socket
 Liên kết với một IPEndPoint cục bộ
 Lắng nghe kết nối
 Chấp nhận kết nối
 Gửi nhận dữ liệu theo giao thức đã thiết lập
 Đóng kết nối sau khi đã hoàn thành vả trở lại trạng thái lắng nghe
chờ kết nối mới.
//Khai báo thư viện và tạo cấu trúc con trỏ kiểu danh sách liên kết.
// stdafx.h : include file for standard system include files, 
//  or project specific include files that are used frequently, but 
//      are changed infrequently 
// 
 
#if !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_) 
#define AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_ 
 
#if _MSC_VER > 1000 
#pragma once 
#endif // _MSC_VER > 1000 
 
#define WIN32_LEAN_AND_MEAN  
// Exclude rarely‐used stuff from Windows headers 
 
#include <windows.h> 
#include <stdio.h> 
#include <commctrl.h> 
#include <WINSOCK2.H> 
#include <Ws2tcpip.h> 
#include "resource.h" 
#pragma comment (lib,"ws2_32.lib") 

#pragma comment (lib,"comctl32.lib") 
#define SERVERPORT 2000 
#define IDCODE 200 
 
typedef struct _tagLinkNode 

 
char* pName; 
 
sockaddr_in sinIPClient; 
 
_tagLinkNode* next; 
}LinkNode; 

 
Đồ án môn học Lập trình mạng SV: Phạm Vũ Thoại – 09TC 
 

Trang: 7 


 
// TODO: reference additional headers your program requires here 
 
//{{AFX_INSERT_LOCATION}} 
// Microsoft Visual C++ will insert additional declarations immediately before the 
previous line. 
 
#endif // !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_) 
 


//Chương trình chính
 
// ServerChar__0971060.cpp : Defines the class behaviors for the application. 
// 
 
#include "stdafx.h" 
HINSTANCE hAppHinst; 
char buffer[MAX_PATH]; 
sockaddr_in sinServerAddr,ClntAddr; 
hostent* pMyServer; 
struct in_addr addr; 
LV_ITEM lvItem; 
int iRecv,iRow,iClntAddrLen,iResult; 
u_long myIP; 
SOCKET ListenSocket,ClientSocket,UpdateSocket; 
BOOL bServerState; 
HANDLE ServerThead; 
HWND hAppHwnd; 
LinkNode *found; 
LV_FINDINFO lvf; 
BOOL CALLBACK WndProc(HWND, UINT, WPARAM,LPARAM); 
DWORD WINAPI WaitForClient(LPVOID ); 
 
int APIENTRY WinMain(HINSTANCE hInstance, 
                     HINSTANCE hPrevInstance, 
                     LPSTR     lpCmdLine, 
                     int       nCmdShow) 

 

INITCOMMONCONTROLSEX InitCtrls; 
 
InitCtrls.dwICC = ICC_INTERNET_CLASSES|ICC_LISTVIEW_CLASSES; 
 
InitCtrls.dwSize = sizeof(INITCOMMONCONTROLSEX); 
 
InitCommonControlsEx(&InitCtrls); 
 
 
 
//khoi dong winsock  
 
WSADATA SData; 
 
 
 
if (WSAStartup(MAKEWORD(2,2),&SData)) 
 

 
 
MessageBox(NULL,"WSAStartup failed!", 
 
 
 
"Client Chat", 
 
 
 
MB_OK|MB_ICONSTOP); 

 
 
return 1; 
 
 

 
hAppHinst = hInstance; 
 
//HICON m_hIcon; 
 
//m_hIcon = AfxGetApp()‐>LoadIcon(IDI_ICON1); 
 
static int iResult = 
DialogBoxParam(hInstance,MAKEINTRESOURCE(IDD_DIALOG1),NULL,WndProc,0); 
 
WSACleanup(); 
 
return iResult; 

 
Đồ án môn học Lập trình mạng SV: Phạm Vũ Thoại – 09TC 
 

Trang: 8 



/************************************************************************/ 
//danh sach lien ket 

void InitLinkList(LinkNode** pHead) 

 
*pHead = NULL; 

 
LinkNode *InsertNode(LinkNode **pHead,char *ClientName,sockaddr_in ClientIP) 

 
LinkNode *new_node,*curr_node = *pHead;     
 
int len; 
 
//tao mot node moi tro toi NULL de chen vao cuoi danh sach 
 
new_node=(LinkNode *)GlobalAlloc(GMEM_ZEROINIT,sizeof(LinkNode)); 
 
new_node‐>pName =(char *)GlobalAlloc(GMEM_ZEROINIT,(len 
=lstrlen(ClientName))+1); 
 
strncpy(new_node‐>pName,ClientName,len); 
 
new_node‐>sinIPClient = ClientIP; 
 
new_node‐>next=*pHead; // them node moi vao dau danh sach 
 
return (*pHead=new_node); 

/************************************************************************/ 
//tim node dau tien co data phu hop 

//tra ve vi tri tim duoc , khong tim thay tra ve NULL 
LinkNode* FindByClientName(LinkNode *Head,char *ClientName) 

 
while((Head)&&lstrcmp(Head‐>pName,ClientName)) 
 
 
Head = Head‐>next; 
    return Head; 

/************************************************************************/ 
LinkNode* FindByClientIP(LinkNode *Head,sockaddr_in ClientIP) 

 
while((Head)&&((Head‐>sinIPClient).sin_addr.s_addr!=ClientIP.sin_addr.s_addr)) 
 
 
Head = Head‐>next; 
    return Head; 

/************************************************************************/ 
int DeleteByClientName(LinkNode **pHead,char *ClientName) 

 
LinkNode *pPrevNode =NULL, *pCurrNode = *pHead; 
 
while((pCurrNode)&&lstrcmp(pCurrNode‐>pName,ClientName)) 
 

 

 
pPrevNode = pCurrNode; 
 
 
pCurrNode = pCurrNode‐>next; 
 

    if (pCurrNode) 
    { 
 
 
if (pPrevNode) 
 
 
 
pPrevNode‐>next= pCurrNode‐>next; 
 
 
else 
 
 
 
*pHead = pCurrNode‐>next; 
 
 
 
GlobalFree(pCurrNode‐>pName); 
 
 
 

GlobalFree(pCurrNode); 
 

 
 
return 1; 
 
return 0; 

/************************************************************************/ 
int DeleteByClientIP(LinkNode **pHead,sockaddr_in ClientIP) 

 
LinkNode *pPrevNode = NULL, *pCurrNode = *pHead; 

 
Đồ án môn học Lập trình mạng SV: Phạm Vũ Thoại – 09TC 
 

Trang: 9 


 
while((pCurrNode)&&((pCurrNode‐
>sinIPClient).sin_addr.s_addr!=ClientIP.sin_addr.s_addr)) 
 

 
 
pPrevNode = pCurrNode; 

 
 
pCurrNode = pCurrNode‐>next; 
 

 
    if (pCurrNode) 
    { 
 
 
if (pPrevNode) 
 
 
 
pPrevNode‐>next= pCurrNode‐>next; 
 
 
else 
 
 
 
*pHead = (*pHead)‐>next; 
 
 
GlobalFree(pCurrNode‐>pName); 
 
 
GlobalFree(pCurrNode); 
 
 

return 1; 
 

 
 
return 0; 

/************************************************************************/ 
void DestroyList(LinkNode **pHead) 

 
LinkNode *pPrev; 
while (*pHead) 
 
 

 
 
pPrev = *pHead; 
 
 
*pHead = (*pHead)‐>next; 
 
 
GlobalFree(pPrev‐>pName); 
 
 
GlobalFree(pPrev); 
 



void UpdateListForClient(LinkNode *pListHead,LinkNode *StartNode) 

 
char *pcBufferToSend; 
 
DWORD len; 
 
LinkNode *pUpdateNode,*pCurrNode; 
 
 
for(pUpdateNode =StartNode;pUpdateNode;pUpdateNode = pUpdateNode‐>next) 
 

 
 
UpdateSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_IP); 
 
 
if (UpdateSocket!=INVALID_SOCKET) 
 
 

 
 
 
if(connect(UpdateSocket,(struct sockaddr*)&(pUpdateNode‐
>sinIPClient),sizeof(pUpdateNode‐>sinIPClient))!=SOCKET_ERROR) 
 
 

 

 
 
 
 
pCurrNode = pListHead; 
 
 
 
 
ZeroMemory(buffer,10); 
 
 
 
 
strncpy(buffer,"Update",6); 
 
 
 
 
*((DWORD*)(buffer+6)) = lstrlen(pCurrNode‐>pName); 
 
 
 
 
iResult = send(ClientSocket,buffer,10,0); 
 
 
 

 
 
 
 
 
 
// lan luot gui tat ca cac nut con lai trong danh sach  
 
 
 
 
for(;pCurrNode;pCurrNode = pCurrNode‐>next) 
 
 
 
 

 
 
 
 
 
 
len = lstrlen(pCurrNode‐>pName); 
 
 
 
 
 
pcBufferToSend =(char*) 

GlobalAlloc(GMEM_ZEROINIT,8+len); 
 
 
 
 
 
if(pcBufferToSend[0] = (pCurrNode‐>next!=NULL))// 
con tiep 
 
 
 
 
 
 
*((DWORD*)(pcBufferToSend+1)) = 
lstrlen((pCurrNode‐>next)‐>pName); //xac dinh size cua phan tu ke tiep 
 
 
 
 
 
else 

 
Đồ án môn học Lập trình mạng SV: Phạm Vũ Thoại – 09TC 
 

Trang: 10 



 
 
 
 
 
 
*((DWORD*)(pcBufferToSend+1)) = 0; 
 
 
 
 
 
MoveMemory(pcBufferToSend+5,pCurrNode‐>pName,len); 
 
 
 
 
 
iResult = 
send(ClientSocket,pcBufferToSend,8+len,0); 
 
 
 
 
 
 
 
 
GlobalFree(pcBufferToSend); 
 

 
 
 

 
 
 

 
 
 
closesocket(UpdateSocket); 
 
 

 


 
void SendMessageToClient(LinkNode *pListHead,char *sentmes) 

 
LinkNode *pUpdateNode; 
 
char temp[10] = "Messag"; 
 
 
//  
ZeroMemory(temp,10); 
//  

strncpy(temp,"Messag",6); 
 
for(pUpdateNode =pListHead;pUpdateNode;pUpdateNode = pUpdateNode‐>next) 
 

 
 
UpdateSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_IP); 
 
 
if (UpdateSocket!=INVALID_SOCKET) 

 
 
 
 
 
iResult = connect(UpdateSocket,(struct sockaddr*)&(pUpdateNode‐
>sinIPClient),sizeof(pUpdateNode‐>sinIPClient)); 
 
 
 
if(iResult!=SOCKET_ERROR) 
 
 
 

 
 
 

 
iResult = send(ClientSocket,temp,10,0); 
 
 
 
 
iResult = send(ClientSocket,sentmes,lstrlen(sentmes),0);
 
 
 
 
 
 
 

 
 
 
closesocket(UpdateSocket); 
 
 

 


 
/************************************************************************/ 
DWORD WINAPI WaitForClient(LPVOID parameter) 

 

LinkNode *pListHead,*found; 
 
InitLinkList(&pListHead); 
 
LV_ITEM lvi; 
 
lvi.mask= LVIF_TEXT; 
 
lvi.iSubItem = 0; 
 
iRow = 0; 
 
 
 
for (;;) 
 

 
 
Sleep(1); 
 
 
iClntAddrLen = sizeof(ClntAddr); 
 
 
ClientSocket = accept(ListenSocket,(struct 
sockaddr*)&ClntAddr,&iClntAddrLen); 
 
 
 

if(ClientSocket!=INVALID_SOCKET) 
 
 
 

 
 
 
 
ZeroMemory(buffer,6); 
 
 
 
 
iRecv = recv(ClientSocket,buffer,6,0); 
 
 
 
 
if (!strncmp(buffer,"Client",6)) 
 
 
 
 

 
 
 
 
 

ZeroMemory(buffer,sizeof(buffer)); 
 
 
 
 
 
recv(ClientSocket,buffer,sizeof(buffer),0); 
 
 
 
 
 
if(!FindByClientName(pListHead,buffer)) 

 
Đồ án môn học Lập trình mạng SV: Phạm Vũ Thoại – 09TC 
 

Trang: 11 


 
 
 
 
 

 
 
 

 
 
 
InsertNode(&pListHead,(char*)buffer,ClntAddr); 
 
 
 
 
 
 
lvi.iItem = iRow++; 
 
 
 
 
 
 
lvi.pszText = (char*)buffer; 
 
 
 
 
 
 
SendDlgItemMessage(hAppHwnd,IDC_LIST2,LVM_SETITEM,0,(LPARAM)&lvi); 
 
 
 
 
 

 
SendDlgItemMessage(hAppHwnd,IDC_LIST2,LVM_INSERTITEM,0,(LPARAM)&lvi); 
 
 
 
 
 
 
 
 
 
 
 
 
 
//gui tra IP 
 
 
 
 
 
 
iResult = 
send(ClientSocket,(char*)&ClntAddr,sizeof(ClntAddr),0); 
 
 
 
 
 
 

// lan luot gui tat ca cac nut con lai trong 
danh sach  
 
 
 
 
 
 
closesocket(ClientSocket); 
 
 
 
 
 
 
UpdateListForClient(pListHead,pListHead); 
 
 
 
 
 
 
 
 
 
 
 

 
 

 
 
 
 
 

 
 
 
 
else if(!strncmp(buffer,"Signout",6)) 
 
 
 
 

 
 
 
 
 
ZeroMemory(buffer,sizeof(buffer)); 
 
 
 
 
 
recv(ClientSocket,buffer,sizeof(buffer),0); 
 
 

 
 
 
if(found = FindByClientName(pListHead,buffer)) 
 
 
 
 
 

 
 
 
 
 
 
lvf.flags = LVFI_STRING; 
 
 
 
 
 
 
lvf.psz = found‐>pName; 
 
 
 
 
 
 

iResult = 
SendDlgItemMessage(hAppHwnd,IDC_LIST2,LVM_FINDITEM,‐1,(LPARAM)&lvf); 
 
 
 
 
 
 
if (iResult!=‐1) 
 
 
 
 
 
 

 
 
 
 
 
 
 
closesocket(ClientSocket); 
 
 
 
 
 
 

 
SendDlgItemMessage(hAppHwnd,IDC_LIST2,LVM_DELETEITEM,(WPARAM)iResult,0); 
 
 
 
 
 
 
 
DeleteByClientName(&pListHead,found‐
>pName); 
 
 
 
 
 
 
 
//update 
 
 
 
 
 
 
 
UpdateListForClient(pListHead,pListHead); 
 
 
 

 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 


 
 
 
 
 
else if(!strncmp(buffer,"Messag",6)) 
 
 
 
 

if(found = FindByClientIP(pListHead,ClntAddr)) 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 
ZeroMemory(buffer,sizeof(buffer)); 

 
 
 
 
 
 
recv(ClientSocket,buffer,sizeof(buffer),0); 
 
 
 
 
 
 
closesocket(ClientSocket); 
 
 
 
 
 
 
SendMessageToClient(pListHead,buffer); 
 
 
 
 
 

 
 
 

 
 
 
 
 
 
 

 
 
 
 
 
 
else if(!strncmp(buffer,"Dua IP",6)) 
 
 
 
 


 
Đồ án môn học Lập trình mạng SV: Phạm Vũ Thoại – 09TC 
 

Trang: 12 


 
 

 
 
 
found = 
FindByClientName(pListHead,(char*)(buffer+10)); 
 
 
 
 
 
ZeroMemory(buffer,sizeof(buffer)); 
 
 
 
 
 
if (found) 
 
 
 
 
 
 
MoveMemory(buffer,&(found‐
>sinIPClient),sizeof(found‐>sinIPClient)); 
 
 
 
 
 

send(ClientSocket,buffer,sizeof(found‐
>sinIPClient),0);   
 
 
 
 
 
 
closesocket(ClientSocket); 
 
 
 
 

 
 
 
 
 
 
 
 

 

 

BOOL CALLBACK WndProc( 
 
 

 
 
 
   
 
 
 
 
 
  HWND hwndDlg, 
// handle to dialog box 
 
 
 
 
 
  UINT uMsg,  // message 
 
 
 
 
 
  WPARAM wParam, 
// first message parameter 
 
 
 
 
 
  LPARAM lParam  

// second message parameter 
 
 
 
 
 
  ) 

 
LV_COLUMN lvcItem; 
 
 
switch (uMsg) 
 

 
case WM_CLOSE: 
 
 
if (ListenSocket!=INVALID_SOCKET) 
 
 
 
 
 
closesocket(ListenSocket); 
 
 
EndDialog(hwndDlg,0); 
 

 
break; 
 
case WM_INITDIALOG: 
 
 
hAppHwnd = hwndDlg; 
 
 
bServerState = FALSE; 
 
 
lvcItem.mask = LVCF_TEXT|LVCF_WIDTH; 
 
 
lvcItem.pszText = "My IP Address"; 
 
 
lvcItem.cx = 150; 
 
 
lvcItem.fmt = LVCFMT_LEFT; 
 
 
SendDlgItemMessage(hwndDlg,IDC_LIST1,LVM_INSERTCOLUMN,0,(LPARAM)&lvcItem); 
 
 
lvcItem.pszText = "Client Connected"; 
 
 

lvcItem.cx = 300; 
 
 
SendDlgItemMessage(hwndDlg,IDC_LIST2,LVM_INSERTCOLUMN,0,(LPARAM)&lvcItem); 
 
 
 
 
 
break; 
 
 
break; 
 
case WM_COMMAND: 
 
 
switch (LOWORD(wParam)) 
 
 

 
 
case IDC_BUTTON1: 
 
 
 
if (bServerState==FALSE) 
 
 

 

 
 
 
 
ZeroMemory(buffer,sizeof(buffer)); 
 
 
 
 
gethostname(buffer,sizeof(buffer)); 
 
 
 
 
pMyServer = gethostbyname(buffer); 
 
 
 
 
SendDlgItemMessage(hwndDlg,IDC_BUTTON1,WM_SETTEXT,0,(LPARAM)"Stop Server"); 
 
 
 
 
 
 
 
 

 
SendDlgItemMessage(hwndDlg,IDC_LIST1,LVM_DELETEALLITEMS,0,0); 

 
Đồ án môn học Lập trình mạng SV: Phạm Vũ Thoại – 09TC 
 

Trang: 13 


 
 
 
 
lvItem.mask= LVIF_TEXT; 
 
 
 
 
lvItem.iSubItem = 0; 
 
 
 
 
int i=0; 
 
 
 
 
while (pMyServer‐>h_addr_list[i] != 0) 

 
 
 
 

 
 
 
 
 
lvItem.iItem = i; 
 
 
 
 
 
addr.s_addr = *(u_long *) pMyServer‐
>h_addr_list[i++]; 
 
 
 
 
 
lvItem.pszText = inet_ntoa(addr); 
 
 
 
 
 
SendDlgItemMessage(hwndDlg,IDC_LIST1,LVM_SETITEM,0,(LPARAM)&lvItem); 

 
 
 
 
 
SendDlgItemMessage(hwndDlg,IDC_LIST1,LVM_INSERTITEM,0,(LPARAM)&lvItem); 
 
 
 
 

 
 
 
 
ListenSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_IP); 
 
 
 
 
if (ListenSocket == INVALID_SOCKET)  
 
 
 
 

 
 
 
 

 
MessageBox(NULL,"Invalid Socket","chat 
Server",MB_OK); 
 
 
 
 
 
return FALSE; 
 
 
 
 

 
 
 
 
sinServerAddr.sin_addr.s_addr = *(u_long *) pMyServer‐
>h_addr_list[0]; 
 
 
 
 
sinServerAddr.sin_family = AF_INET; 
 
 
 
 
sinServerAddr.sin_port = SERVERPORT; 

 
 
 
 
 
 
 
 
iResult = bind( ListenSocket, (struct 
sockaddr*)&sinServerAddr,sizeof(sinServerAddr)); 
 
 
 
 
if (iResult == SOCKET_ERROR)  
 
 
 
 

 
 
 
 
 
MessageBox(NULL,"Invalid Bind","chat 
Server",MB_OK); 
 
 
 

 
 
return FALSE; 
 
 
 
 

 
 
 
 
 
iResult = listen(ListenSocket, SOMAXCONN); 
 
 
 
 
if (iResult == SOCKET_ERROR){ 
 
 
 
 
 
MessageBox(NULL,"Invalid Listen","chat 
Server",MB_OK); 
 
 
 
 

 
return FALSE; 
 
 
 
 

 
 
 
 
ServerThead = 
CreateThread(NULL,0,WaitForClient,NULL,0,NULL); 
 
 
 
 
 
bServerState=TRUE; 
 
 
 

 
 
 
else 
 
 
 


 
 
 
 
TerminateThread(ServerThead,0); 
 
 
 
 
closesocket(ListenSocket); 
 
 
 
 
SendDlgItemMessage(hwndDlg,IDC_LIST1,LVM_DELETEALLITEMS,0,0); 
 
 
 
 
SendDlgItemMessage(hwndDlg,IDC_LIST2,LVM_DELETEALLITEMS,0,0); 
 
 
 
 
SendDlgItemMessage(hwndDlg,IDC_BUTTON1,WM_SETTEXT,0,(LPARAM)"Start Server"); 
 
 
 
 

bServerState=FALSE; 
 
 
 

 
 
 
break; 
 
 
default: 
 
 
 
return FALSE; 
 
 


 
Đồ án môn học Lập trình mạng SV: Phạm Vũ Thoại – 09TC 
 

Trang: 14 


 
 
 

 
 
 
 


 

break; 

default: 
 
return FALSE; 

return TRUE; 

// Thiết kế form và các thuộc tính của form

 
Đồ án môn học Lập trình mạng SV: Phạm Vũ Thoại – 09TC 
 

Trang: 15 


4.2 Viết chương trình cho phía máy Client
 Xác định địa chỉ Server
 Tạo Socket
 Gửi nhận dữ liệu theo giao thức đã thiết kế
 Đóng Socket


//Khai báo thư viện.
 
// stdafx.h : include file for standard system include files, 
// or project specific include files that are used frequently, 
// but are changed infrequently 
 
// stdafx.h : include file for standard system include files, 
//  or project specific include files that are used frequently, but 
//      are changed infrequently 
// 
 
#if !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_) 
#define AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_ 
 
#if _MSC_VER > 1000 
#pragma once 
#endif // _MSC_VER > 1000 
 
#define WIN32_LEAN_AND_MEAN  
// Exclude rarely‐used stuff from Windows headers 
 
#include <windows.h> 
#include <stdio.h> 
#include <commctrl.h> 
#include <WINSOCK2.H> 
#include "resource.h" 
#pragma comment (lib,"ws2_32.lib") 
#pragma comment (lib,"comctl32.lib") 
#define SERVERPORT 2000 

 
 
// TODO: reference additional headers your program requires here 
 
//{{AFX_INSERT_LOCATION}} 
// Microsoft Visual C++ will insert additional declarations immediately before the 
previous line. 
 
#endif // !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_) 
 

 
Đồ án môn học Lập trình mạng SV: Phạm Vũ Thoại – 09TC 
 

Trang: 16 


//Chương trình chính
 
// ClientChat__0971060.cpp : Defines the class behaviors for the application. 
// 
 
// Client3.cpp : Defines the entry point for the application. 
// 
#include "stdafx.h" 
HINSTANCE hAppHinst; 
HWND hAppHwnd; 
BOOL bLogInState,bPortChecked; 
sockaddr_in sinServerAddr,sinMyAddr,sinClntAddr; 

LV_COLUMN lvcItem; 
LV_ITEM lvItem; 
int iRecv,iRow,iClntAddrLen; 
SOCKET ConnectSocket,FriendSocket,ClntSocket; 
HGLOBAL hGetText; 
DWORD dwConnect; 
char szItemName[MAX_PATH],buffer[MAX_PATH]; 
char *pcBufferToRecv; 
DWORD len; 
BOOL bContRecv; 
 
BOOL CALLBACK WndProc(HWND, UINT, WPARAM,LPARAM); 
DWORD WINAPI Connect2Server(LPVOID); 
DWORD WINAPI WaitForFriend(LPVOID); 
void GetList(DWORD len); 
void ErrorState(); 
 
int APIENTRY WinMain(HINSTANCE hInstance, 
                     HINSTANCE hPrevInstance, 
                     LPSTR     lpCmdLine, 
                     int       nCmdShow) 

 
INITCOMMONCONTROLSEX InitCtrls; 
 
InitCtrls.dwICC = ICC_INTERNET_CLASSES|ICC_LISTVIEW_CLASSES; 
 
InitCtrls.dwSize = sizeof(INITCOMMONCONTROLSEX); 
 
InitCommonControlsEx(&InitCtrls); 

 
//khoi dong winsock  
 
static WSADATA SData; 
 
 
 
if (WSAStartup(MAKEWORD(2,2),&SData)) 
 

 
 
MessageBox(NULL,"WSAStartup failed!","Client",MB_OK|MB_ICONSTOP); 
 
 
return 1; 
 

 
 
 
hAppHinst = hInstance; 
 
static int iResult = 
DialogBoxParam(hInstance,MAKEINTRESOURCE(IDD_DIALOG1),NULL,WndProc,0); 
 
WSACleanup(); 
 
return iResult; 


 
/************************************************************************/ 
void ErrorState() 

 
 
SendDlgItemMessage(hAppHwnd,IDC_EDIT5,WM_SETTEXT,0,(LPARAM)"Server not found"); 
 
MessageBox(hAppHwnd,"Connect Failure","Client Chat",MB_OK); 
 
EnableWindow(GetDlgItem(hAppHwnd,IDC_EDIT1),TRUE); 
 
EnableWindow(GetDlgItem(hAppHwnd,IDC_IPADDRESS1),TRUE); 

 
Đồ án môn học Lập trình mạng SV: Phạm Vũ Thoại – 09TC 
 

Trang: 17 


 
EnableWindow(GetDlgItem(hAppHwnd,IDC_CHECK3),TRUE); 
 
EnableWindow(GetDlgItem(hAppHwnd,IDC_BUTTON1),TRUE); 
 
if(SendDlgItemMessage(hAppHwnd,IDC_CHECK3,BM_GETCHECK,0,0)==BST_CHECKED) 
 
 
EnableWindow(GetDlgItem(hAppHwnd,IDC_EDIT4),TRUE); 

 
else 
 
 
EnableWindow(GetDlgItem(hAppHwnd,IDC_EDIT4),FALSE); 
 
SendDlgItemMessage(hAppHwnd,IDC_EDIT5,WM_SETTEXT,0,(LPARAM)"Ready"); 

 
/****************************************************************/ 
BOOL CALLBACK WndProc(HWND hwndDlg, 
// handle to dialog box 
 
 
 
 
 
  UINT uMsg,   
// message 
 
 
 
 
 
  WPARAM wParam, 
// first message parameter 
 
 
 
 

 
  LPARAM lParam  
// second message parameter 
 
 
 
 
 
 ) 

 
switch (uMsg) 
 

 
case WM_CLOSE: 
if (ConnectSocket!=INVALID_SOCKET) 
 
 
 
 
 
closesocket(ConnectSocket); 
 
 
EndDialog(hwndDlg,0); 
 
 
break; 
 

case WM_INITDIALOG: 
 
 
// thiet lap cac gia tri mac dinh 
 
 
ZeroMemory(buffer,MAX_PATH); 
 
 
hAppHwnd = hwndDlg; 
 
 
bLogInState= FALSE; 
 
 
 
 
 
// thiet lap hien thi  
 
 
EnableWindow(GetDlgItem(hwndDlg,IDC_EDIT1),TRUE); 
 
 
EnableWindow(GetDlgItem(hwndDlg,IDC_IPADDRESS1),TRUE); 
 
 
EnableWindow(GetDlgItem(hwndDlg,IDC_EDIT4),FALSE); 
 
 

SendDlgItemMessage(hwndDlg,IDC_CHECK3,BM_SETCHECK,(WPARAM) 
BST_UNCHECKED,0); 
 
 
SetDlgItemText(hwndDlg,IDC_BUTTON1,"&Log in"); 
 
 
SetFocus(GetDlgItem(hwndDlg,IDC_EDIT1)); 
 
 
EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTON2),FALSE); 
 
 
lvcItem.mask = LVCF_FMT|LVCF_TEXT|LVCF_WIDTH; 
 
 
lvcItem.fmt =LVCFMT_LEFT; 
 
 
lvcItem.pszText = TEXT("Buddy"); 
 
 
lvcItem.cx = 145; 
 
 
SendDlgItemMessage(hwndDlg,IDC_LIST1,LVM_INSERTCOLUMN,0,(LPARAM)&lvcItem); 
 
 
SendDlgItemMessage(hwndDlg,IDC_EDIT5,WM_SETTEXT,0,(LPARAM)"Ready"); 
 

 
break; 
 
case WM_COMMAND: 
 
 
switch (LOWORD(wParam)) 
 
 

 
 
case IDC_EDIT3: 
 
 
 
// kiem tra edit box de thiet lap button Send 
 
 
 
if 
(bLogInState&&GetWindowTextLength(GetDlgItem(hwndDlg,IDC_EDIT3))) 
 
 
 
 
EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTON2),TRUE); 
 
 
 

else 
 
 
 
EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTON2),FALSE); 
 
 
break; 
 
 
 
case IDC_CHECK3: 
 
 
 
// kiem tra checkbox Port  
 
 
 
if(SendDlgItemMessage(hwndDlg,IDC_CHECK3,BM_GETCHECK,0,0)==BST_CHECKED) 

 
Đồ án môn học Lập trình mạng SV: Phạm Vũ Thoại – 09TC 
 

Trang: 18 


 
 

 

 
 
 
 
EnableWindow(GetDlgItem(hwndDlg,IDC_EDIT4),TRUE); 
 
 
 
 
SetFocus(GetDlgItem(hwndDlg,IDC_EDIT4)); 
 
 
 

 
 
 
else  
 
 
 

 
 
 
 
SendDlgItemMessage(hwndDlg,IDC_EDIT4,WM_SETTEXT,0,(LPARAM)""); 
 

 
 
 
EnableWindow(GetDlgItem(hwndDlg,IDC_EDIT4),FALSE); 
 
 
 

 
 
 
break; 
 
 
case IDC_BUTTON2: 
  
 
 
// nhan nut send 
  
 
 
 
ConnectSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_IP); 
  
 
 
 
if (ConnectSocket!=INVALID_SOCKET) 
  

 
 
 

  
 
 
 
 
if (connect(ConnectSocket,(struct 
sockaddr*)&sinServerAddr,sizeof(sinServerAddr))!=SOCKET_ERROR) 
  
 
 
 
 

 
 
 
 
 
 
ZeroMemory(buffer,6); 
 
 
 
 
 
 

strncpy_s(buffer,"Messag",6); 
 
 
 
 
 
 
send(ConnectSocket,buffer,6,0); 
 
  
 
 
 
 
 
if(iRecv = 
GetWindowTextLength(GetDlgItem(hwndDlg,IDC_EDIT3))) 
  
 
 
 
 
 

  
 
 
 
 
 

 
hGetText = 
GlobalAlloc(GMEM_ZEROINIT,iRecv+=2+GetWindowTextLength(GetDlgItem(hwndDlg,IDC_EDIT1)))

 
 
 
 
 
 
 
GetDlgItemText(hwndDlg,IDC_EDIT1,(LPSTR)hGetText,iRecv); 
 
 
 
 
 
 
 
*((char*)((DWORD)hGetText+lstrlen((LPSTR)hGetText))) = ':'; 
  
 
 
 
 
 
 
 
 
 

 
 
 
 
 
GetDlgItemText(hAppHwnd,IDC_EDIT3,(LPSTR)((DWORD)hGetText+lstrlen((LPSTR)hGetTe
xt)),iRecv); 
  
 
 
 
 
 
 
send(ConnectSocket,(char*)hGetText,iRecv,0); 
  
 
 
 
 
 
 
GlobalFree(hGetText); 
  
 
 
 
 
 


  
 
 
 
 

  
 
 
 
 
closesocket(ConnectSocket); 
 
 
 
 
 
SendDlgItemMessage(hAppHwnd,IDC_EDIT3,WM_SETTEXT,0,(LPARAM)""); 
 
 
 
 
 
EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTON2),FALSE); 
 
 
 
 
 
SetFocus(GetDlgItem(hwndDlg,IDC_EDIT3)); 

  
 
 
 

 
 
 
 
break; 
 
 
case IDC_BUTTON1: 
 
 
 
if (bLogInState==FALSE) 
 
 
 

 
 
 
 
 
// kiem tra dieu kien , truoc khi dang nhap 
 
 
 

 
if(!GetWindowTextLength(GetDlgItem(hwndDlg,IDC_EDIT1))) 
 
 
 
 
 
break; 
 
 
 
 
if(((bPortChecked = 
SendDlgItemMessage(hwndDlg,IDC_CHECK3,BM_GETCHECK,0,0))==BST_CHECKED)&& 
 
 
 
 
 
(!GetWindowTextLength(GetDlgItem(hwndDlg,IDC_EDIT4)))) 
 
 
 
 
 
break; 

 
Đồ án môn học Lập trình mạng SV: Phạm Vũ Thoại – 09TC 
 


Trang: 19 


 
 
 
 
// thuc hien ket noi toi server 
 
 
 
 
CreateThread(NULL,0, Connect2Server,NULL,0,&dwConnect); 
 
 
 
 
 
 
 

 
 
 
else 
 
 
 


 
 
 
 
if(FriendSocket!=INVALID_SOCKET) 
 
 
 
 
 
closesocket(FriendSocket); 
 
 
 
 
// gui tin hieu thoat 
 
 
 
 
ZeroMemory(buffer,sizeof(buffer)); 
 
 
 
 
lstrcpy(buffer,"Signou"); 
 
 
 
 

ConnectSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_IP); 
 
 
 
 
if (ConnectSocket!=INVALID_SOCKET) 
 
 
 
 

 
 
 
 
 
connect(ConnectSocket,(struct 
sockaddr*)&sinServerAddr,sizeof(sinServerAddr)); 
 
 
 
 
 
send(ConnectSocket,buffer,lstrlen(buffer),0); 
 
 
 
 
 
GetDlgItemText(hAppHwnd,IDC_EDIT1,buffer,sizeof(buffer)); 

 
 
 
 
 
send(ConnectSocket,buffer,lstrlen(buffer),0); 
 
 
 
 
 
closesocket(ConnectSocket); 
 
 
 
 

 
bLogInState= FALSE; 
 
 
 
 
 
 
 
 
//Sau khi dang xuat, thiet lap cac cua so hien thi  
 
 

 
 
EnableWindow(GetDlgItem(hwndDlg,IDC_EDIT1),TRUE); 
 
 
 
 
EnableWindow(GetDlgItem(hwndDlg,IDC_IPADDRESS1),TRUE); 
 
 
 
 
EnableWindow(GetDlgItem(hwndDlg,IDC_CHECK3),TRUE); 
 
 
 
 
SendMessage(hwndDlg,WM_COMMAND,(WPARAM)IDC_CHECK3,0); 
 
 
 
 
SetDlgItemText(hwndDlg,IDC_BUTTON1,"&Log in"); 
 
 
 
 
SetDlgItemText(hwndDlg,IDC_EDIT3,""); 
 
 

 
 
SendDlgItemMessage(hwndDlg,IDC_LIST1,LVM_DELETEALLITEMS,0,0); 
 
 
 
 
EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTON2),FALSE); 
 
 
 
 
SendDlgItemMessage(hAppHwnd,IDC_EDIT5,WM_SETTEXT,0,(LPARAM)"Logged out"); 
 
 
 
 
 
 
 

 
 
 
break; 
 
 
default: 
 
 

 
return FALSE; 
 
 

 
 
break; 
 
default: 
 
 
return FALSE; 

 
 
return TRUE; 

/************************************************************************/ 
DWORD WINAPI Connect2Server(LPVOID lpParameter) 

 
 
 
//khoi tao socket 
 
ConnectSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_IP); 
 
if(ConnectSocket==INVALID_SOCKET) 
 

 
goto ONERROR; 
 
 
 
// thiet lap IP  
 
sinServerAddr.sin_family = AF_INET; 
 
ZeroMemory(buffer,MAX_PATH); 
 
GetDlgItemText(hAppHwnd,IDC_IPADDRESS1,buffer,sizeof(buffer)‐1); 
 
sinServerAddr.sin_addr.s_addr = inet_addr(buffer); 

 
Đồ án môn học Lập trình mạng SV: Phạm Vũ Thoại – 09TC 
 

Trang: 20 


 
// thiet lap Port 
 
if (bPortChecked==BST_CHECKED) 
 
 
sinServerAddr.sin_port = GetDlgItemInt(hAppHwnd,IDC_EDIT4,NULL,FALSE); 
 

else 
 
 
sinServerAddr.sin_port =SERVERPORT; 
 
// hien thi trang thai tren Dialog 
 
SendDlgItemMessage(hAppHwnd,IDC_EDIT5,WM_SETTEXT,0,(LPARAM)"Connecting to 
server ..."); 
 
EnableWindow(GetDlgItem(hAppHwnd,IDC_EDIT1),FALSE); 
 
EnableWindow(GetDlgItem(hAppHwnd,IDC_IPADDRESS1),FALSE); 
 
EnableWindow(GetDlgItem(hAppHwnd,IDC_EDIT4),FALSE); 
 
EnableWindow(GetDlgItem(hAppHwnd,IDC_CHECK3),FALSE); 
 
EnableWindow(GetDlgItem(hAppHwnd,IDC_BUTTON1),FALSE); 
 
 
 
// bat dau ket noi toi server  
 
if (connect(ConnectSocket,(struct 
sockaddr*)&sinServerAddr,sizeof(sinServerAddr))==SOCKET_ERROR) 
 

closesocket(ConnectSocket); 
 

 
ONERROR: 
 
 
ErrorState();  
 
 
return 0; 
 

 
 
 
// sau khi da ket noi thanh cong 
 
//thiet lap cac trang thai hien thi  
 
EnableWindow(GetDlgItem(hAppHwnd,IDC_BUTTON1),TRUE); 
 
SetDlgItemText(hAppHwnd,IDC_BUTTON1,"&Log out"); 
 
SetFocus(GetDlgItem(hAppHwnd,IDC_EDIT3)); 
 
SendDlgItemMessage(hAppHwnd,IDC_EDIT5,WM_SETTEXT,0,(LPARAM)"Connected 
Successfully"); 
 
bLogInState= TRUE; 
 
 
 

// gui ten toi server 
 
 
ZeroMemory(buffer,MAX_PATH); 
 
GetDlgItemText(hAppHwnd,IDC_EDIT1,buffer,sizeof(buffer)); 
 
iRecv =7+GetWindowTextLength(GetDlgItem(hAppHwnd,IDC_EDIT1)); 
pcBufferToRecv =(char*) GlobalAlloc(GMEM_ZEROINIT,iRecv); 
 
 
wsprintf(pcBufferToRecv,"Client%s",buffer); 
 
send(ConnectSocket,pcBufferToRecv,iRecv,0); 
 
GlobalFree(pcBufferToRecv); 
 
// nhan lai IP 
 
recv(ConnectSocket,(char*)&sinMyAddr,sizeof(sinMyAddr),0); 
 
closesocket(ConnectSocket);// ket thuc giao dich khoi dau  
 
 
 
//tao socket de nhan tin nhan  
 
FriendSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_IP);// khoi tao socket cho 
MyIP 
 

if (FriendSocket!=INVALID_SOCKET) 
 

 
 
iRecv =  bind(FriendSocket,(struct 
sockaddr*)&sinMyAddr,sizeof(sinMyAddr)); 
 
 
iRecv = listen(FriendSocket,SOMAXCONN); 
 
// thuc hien cho thong diep toi 
 
 
CreateThread(NULL,0,WaitForFriend,NULL,0,NULL); 
  

 
return 0; 
 
 

/*****************************************/ 
void AddText(char *buffer) 


 
Đồ án môn học Lập trình mạng SV: Phạm Vũ Thoại – 09TC 
 


Trang: 21 


 
 
 
HANDLE hBufferToPrint = GlobalAlloc(GMEM_ZEROINIT,lstrlen(buffer)+4); 
 
wsprintf((LPSTR)hBufferToPrint,"%s%c%c",buffer,13,10); 
 
int iTxtLen =1+GetWindowTextLength(GetDlgItem(hAppHwnd,IDC_EDIT2)); 
 
if(iTxtLen) 
 

 
 
SendDlgItemMessage(hAppHwnd,IDC_EDIT2,EM_SETSEL,iTxtLen,iTxtLen); 
 
 
SendDlgItemMessage(hAppHwnd,IDC_EDIT2,EM_REPLACESEL,0,(LPARAM)hBufferToPrint); 
 

 
else 
 

 
 
SendDlgItemMessage(hAppHwnd,IDC_EDIT2,WM_SETTEXT,0,(LPARAM)hBufferToPrint); 

 

 
 
 
GlobalFree(hBufferToPrint); 
 
 

DWORD WINAPI WaitForFriend(LPVOID parameter) 

 
DWORD len; 
 
int iResult; 
 
 
 
iClntAddrLen = sizeof(sinClntAddr); 
 
for (;bLogInState;) 
 

 
 
Sleep(1); 
 
 
ClntSocket = accept(FriendSocket,(struct 
sockaddr*)&sinClntAddr,&iClntAddrLen); 

 
 
 
 
 
if(ClntSocket!=SOCKET_ERROR) 
 
 

 
 
 
ZeroMemory(buffer,sizeof(buffer)); 
 
 
 
iResult = recv(ClntSocket,buffer,10,0); 
 
 
 
len=*((DWORD*)(buffer+6)); 
 
 
 
 
if(!strncmp((char*)buffer,"Update",6)) 
 
 
 


 
 
 
 
SendDlgItemMessage(hAppHwnd,IDC_LIST1,LVM_DELETEALLITEMS,0,0); 
 
 
 
 
lvItem.mask= LVIF_TEXT; 
 
 
 
 
lvItem.iSubItem = 0; 
 
 
 
 
iRow = 0; 
 
 
 
 
do  
 
 
 
 


 
 
 
 
 
pcBufferToRecv = 
(char*)GlobalAlloc(GMEM_ZEROINIT,8+len); 
 
 
 
 
 
iResult = recv(ClntSocket,pcBufferToRecv,8+len,0); 
 
 
 
 
 
lvItem.iItem = iRow++; 
 
 
 
 
 
lvItem.pszText =(char*)(pcBufferToRecv+5); 
 
 
 
 
 

SendDlgItemMessage(hAppHwnd,IDC_LIST1,LVM_SETITEM,0,(LPARAM)&lvItem); 
 
 
 
 
 
SendDlgItemMessage(hAppHwnd,IDC_LIST1,LVM_INSERTITEM,0,(LPARAM)&lvItem); 
 
 
 
 
 
len = *((DWORD*)(pcBufferToRecv+1)); 
 
 
 
 
 
bContRecv = BOOL(*pcBufferToRecv); 
 
 
 
 
 
GlobalFree(pcBufferToRecv); 
 
 
 
 
} while (bContRecv); 

 
 
 
 
 
 
 
 

 
 
 
else 

 
Đồ án môn học Lập trình mạng SV: Phạm Vũ Thoại – 09TC 
 

Trang: 22 


 
 
 
if(!strncmp((char*)buffer,"Messag",6)) 
 
 
 

 

 
 
 
ZeroMemory(buffer,sizeof(buffer)); 
 
 
 
 
recv(ClntSocket,buffer,sizeof(buffer)‐1,0); 
 
 
 
 
AddText(buffer); 
 
 
 

 
 
 
 
closesocket(ClntSocket); 
 
 

 
 
 
 

 
 
 

 
return 0; 

 
void GetList(DWORD a) 

 
SendDlgItemMessage(hAppHwnd,IDC_LIST1,LVM_DELETEALLITEMS,0,0); 
 
len = a; 
 
lvItem.mask= LVIF_TEXT; 
 
lvItem.iSubItem = 0; 
 
iRow = 0; 
 
do  
 

 
 
pcBufferToRecv = (char*)GlobalAlloc(GMEM_ZEROINIT,8+len); 
recv(ConnectSocket,pcBufferToRecv,8+len,0); 
 
 

 
 
lvItem.iItem = iRow++; 
 
 
lvItem.pszText =(char*)(pcBufferToRecv+5); 
 
 
SendDlgItemMessage(hAppHwnd,IDC_LIST1,LVM_SETITEM,0,(LPARAM)&lvItem); 
 
 
SendDlgItemMessage(hAppHwnd,IDC_LIST1,LVM_INSERTITEM,0,(LPARAM)&lvItem); 
 
 
len = *((DWORD*)(pcBufferToRecv+1)); 
 
 
bContRecv = BOOL(*pcBufferToRecv); 
 
 
GlobalFree(pcBufferToRecv); 
 
} while (bContRecv); 

 
 
 
 
 


 
Đồ án môn học Lập trình mạng SV: Phạm Vũ Thoại – 09TC 
 

Trang: 23 


// Thiết kế form và các thuộc tính của form

 
Đồ án môn học Lập trình mạng SV: Phạm Vũ Thoại – 09TC 
 

Trang: 24 


5. Kết quả Demo chương trình
Bước 1:
Chạy tập tin ServerChat__0971060.exe
Chạy nhiều tập tin ClientsChat__0971060.exe

 

Bước 2:
Khởi động Server: nhấn button Start Server; ở đây chương trình sẽ lấy
địa chỉ local host 127.0.0.1 của máy và port .......
Bước 3:
Khởi động Clients
Nhập Nick name : THOAI / THAO
Nhập địa chỉ IP Serser : 127.0.0.1

Kết nối tới máy chủ, nhấn button Login
 
Đồ án môn học Lập trình mạng SV: Phạm Vũ Thoại – 09TC 
 

Trang: 25 


×