Lập trình mạng bằng pocket PC-part 7 ppt

8 717 1
Lập trình mạng bằng pocket PC-part 7 ppt

Đang tải... (xem toàn văn)

Thông tin tài liệu

Đóng Socket : Một khi đã hoàn thành việc sử dụng socket, dù ở trên Server hay Client, chúng ta phải giải phóng tài nguyên thiết bị đã được liên kết với socket đó. Trước khi ta thực sự đóng một socket, ta nên gọi hàm shutdown (). Chúng ta có thể trực tiếp hủy một socket bằng cách đóng nó, nhưng tốt hơn ta nên gọi hàm shutdown() trước tiên bởi vì điều này đảm bảo rằng: tất cả dữ liệu trong hàng đợi vận chuyển TCP đã được gửi hoặc nhận hết trước khi socket bị đóng: int shutdown( SOCKET s , int how) ; Tham số s là handle của socket mà ta muốn đóng. Tham số how xác định cách thức những hàm socket xảy ra sau được xử lý trên socket này. Có ba tùy chọn: SD_RECEIVE, SD_SEND, SE_BOTH. Chọn SD_RECEIVE sẽ ngăn chặn việc gọi hàm recv() và SD_SEND sẽ ngăn chặn việc gọi hàm send(). Rõ ràng SD_BOTH sẽ dừng việc gửi và nhận dữ liệu trên socket (tuy nhiên, tất cả dữ liệu đã nằm trong hàng đợi sẽ được xử lý ). Nếu không có lỗi, hàm shutdown() sẽ trả về 0. Một khi socket đã bị shutdown(), chúng ta không thể dùng nó được nữa, trừ khi chúng ta đóng nó bằng hàm closesocket(). int closesocket(SOCKET s) ; với s làm handle của socket mà ta muốn đóng. Sử dụng MFC: Giới thiệu về lớp CSocket: Hình 3.41 Sơ đồ kế thừa của lớp CSocket. Lớp CSocket kết thừa từ lớp cha của nó là CAsyncSocket, do đó nó thừa hưởng những thành phần Windows sockets API của lớp CasyncSocket.Xem chi tiết trong MSDN. Những phần tiếp theo chúng ta sẽ khảo sát những thành phần cơ bản của lớp CSocket hỗ trợ cho việc lập trình mạng. Client: Để có thể sử dụng được thư viện CSocket, cần phải làm hai công việc, một là thêm dòng #include <afxsock.h> vào đầu tập tin có sử dụng lớp Csocket. Công việc thứ hai cần làm là để có thể sử dụng thư viện CSocket là phải gọi hàm AfxSocketInit(NULL) trước khi sử dụng các hàm của lớp Csocket, mục đích là để khởi tạo thư viện. Nếu không, mọi hàm sử dụng thư viện tuy được biên dịch thành công nhưng vẫn báo lỗi khi thi hành chương trình. Để kết nối đến một cổng chở kết nối, trước tiên ta phải khởi tạo một socket với hàm như sau: BOOL Create(): Hàm tạo socket ở phia Client không có tham số. Nếu việc tạo socket thành công thì hàm sẽ trả về kết quả khác 0; nếu xảy ra lỗi thì hàm sẽ trả về kết quả là 0. Ta có thể dùng hàm int GetLastError() để lấy thông tin mã lỗi. Sau khi đã tạo một socket thành công, bước tiếp theo là ta sẽ dùng socket đó để kết nối đến Server đang mở dịch vụ, ta sẽ dùng hàm sau để kết nối: BOOL Connect(LPCTSTR lpszHostAddress, UINT nHostPort). lpszHostAddress: là địa chỉ của Server mà ta cần kết nối đến. Ta có thể truyền cho tham số này theo tên miền hoặc theo địa chỉ IP. Ví dụ: “ftp.microsoft.com” hoặc “128.56.22.8” đều được. Mỗi máy tính đều có một địa chỉ IP mặc định là “127.0.0.1” hoặc “localhost”. Do đó, nếu như chúng ta thực hành kết nối cho cả Server và Client trên cùng một máy thì ta có thể kết nối đến địa chỉ này. nHostPort: Là số cổng của dịch vụ mà server đang mở. Ví dụ cổng của dịch vụ web là 80, cổng của dịch vụ ftp là 21 Sau đây là ví dụ cho việc tạo và kết nối đến dịch vụ cổng 1111 trên Server. CSocket skConnect; If(!skConnect.Create() || !skConnect.Connect(“localhost”,1111)) { cout<<”ket noi khong thanh cong”<<endl; exit(0); } else cout<<”kết nối thành công”; Sau khi đã kết nối được server, ta sẽ dùng hai hàm sau đây để gửi và nhận thông điệp. Hàm gửi thông điệp: int Send( const void* lpBuf, int nBuffeLen, int nFlags = 0 ); lpBuf: là bộ đệm dùng để chứa dữ liệu được gửi. nBuffeLen: Chiều dài của dữ liệu lpBuf dưới dạng Byte. nFlags: Mặc định là 0, ta có thể không cần truyền tham số này. Nếu không có lỗi xảy ra thì hàm này sẽ trả về giá trị tổng số kí tự được gửi, ( giá trị này phải nhỏ hơn giá trị của nBufLen). Nếu xảy ra lỗi thì hàm sẽ trả về giả trị SOCKET_ERROR. Chúng ta có thể tìm được mã lỗi thông qua hàm int GetLastError(). Xem thêm trong MSDN. Hàm nhận thông điệp từ socket: virtual int Receive(const void* lpBuf, int nBuffeLen, int nFlags = 0); Tất cả những tham số này đều có ý nghĩa tương tự như các tham số của hàm Send() ở trên.Nếu không có lỗi xảy ra thì giá trị trả về của hàm này là tổng số byte nhận được. Nếu đã đóng kết nối socket, thì kết quả trả về là 0. Nếu xảy ra lỗi thì kết quả trả về sẽ là một SOCKET_ERROR được xác định trong hàm int GetLastError(). Tham khảo mã lỗi trong MSDN. Ví dụ sau sẽ trình bày minh họa cho việc gửi và nhận dữ liệu: Char msg[1000]; Int msg_len; While(1) { cout<<”Nhap thong diep: “; gets(msg); msg_len = strlen(msg); //Gửi thông điệp đến server skConnect.Send(&msg_len, sizeof(msg_len)); //Gửi chiều dài thông điệp. skConnect.Send(msg,msg_len);//Gửi nội dung thông điệp. //Nhận thông điệp đến server skConnect.Receive(&msg_len, sizeof(msg_len)); //nhận chiều dài thông điệp. skConnect.Receive(msg,msg_len);//Nhận nội dung thông điệp. } Cuối cùng, sau khi hoàn tất truyền dữ liệu, đóng kết nối với câu lệnh như sau: virtual void Close( ); Sau đây là toàn bộ nội dung đã thực hiện cho client. CSocket skConnect; If(!skConnect.Create() || !skConnect.Connect(“localhost”,1111)) { cout<<”ket noi khong thanh cong”<<endl; exit(0); } else cout<<”kết nối thành công”; Char msg[1000]; Int msg_len; While(1) { cout<<”Nhap thong diep: “; gets(msg); msg_len = strlen(msg); //Gửi thông điệp đến server skConnect.Send(&msg_len, sizeof(msg_len)); //Gửi chiều dài thông điệp. skConnect.Send(msg,msg_len);//Gửi nội dung thông điệp. //Nhận thông điệp đến server skConnect.Receive(&msg_len, sizeof(msg_len)); //nhận chiều dài thông điệp. skConnect.Receive(msg,msg_len);//Nhận nội dung thông điệp. skConnect[msg_len] = 0;//Kết thúc chuỗi. } skConnect.Close(); Server: Cũng tương tự như các phía Client, điều trước tiên chúng ta cần làm là khởi tạo một socket dùng để tạo dịch vụ. Câu lệnh khởi tạo socket phía server có hơi khác so với phía Client. Nguyên mẫu của hàm như sau: BOOL Create(UINT nSocketPort = 0,int nSocketType = SOCK_STREAM,LPCTSTR *lptstr = NULL ); nSocketPort: Số cổng mà ta sử dụng để mở dịch vụ. nSocketType: SOCK_STREAM( tương ứng với giao thức TCP) hoặc là SOCK_DGRAM( tương ứng với giao thức UDP). Mặc định của hàm là SOCK_STREAM. *lptstr: là chuỗi con trỏ chứa địa chỉ mạng của một kết nối socket. Mặc định là NULL. Giá trị khác 0 sẽ được hàm này trả về nếu không có lỗi xảy ra. Ngược lại là 0.Chúng ta có thể tham khảo mã lỗi thông qua hàm int GetLastError(); Trong CSocket, chúng không cần thiết phải gọi hàm bind(), bởi vì sau khi gọi hàm Create() thì tự động hàm bind() sẽ được gọi để kết buộc socket đến địa chỉ xác định. Sau khi đã khởi tạo socket thành công, tiếp theo ta sử dụng hàm Listen để nghe ngóng kết nối. BOOL Listen(int backlog = 5 ); backlog: Chiều dài tối đa có mà hàng đợi của những kết nối vào có thể chứa được. Giá trị này giới hạn trong khoảng từ 1 đến 5; mặc định là 5. Nếu không có lỗi thì hàm này sẽ trả về giá trị khác 0; ngược lại sẽ cho giá trị là 0 và mã lỗi sẽ được xác định thông qua hàm GetLastError. Để chấp nhận một kết nối vào trước tiên cần phải khởi tạo socket bằng hàm Create, sau đó một backlog (dãy) các kết nối vào sẽ được xác định bởi hàm Listen. Sau đó những kết nối này sẽ được chấp nhận bởi hàm Accept. Hàm Listen chỉ áp dụng cho những socket hỗ trợ kết nối, điển hình là dạng SOCK_STREAM. Socket này được đặt ở chế độ “bị động”_ chế độ mà những kết nối vào được thừa nhận và được xếp hàng chờ đợi bởi tiến trình này. Hàm này thường được sử dụng ở Server( hoặc có thể ở bất kỳ ứng dụng nào muốn chấp nhận kết nối vào) cho phép có nhiều hơn một kết nối được yêu cầu ở cùng một thời điểm. Nếu có yêu cầu kết nối nhưng hàng đợi đã đầy(nConnectionBacklog = 5) thì client sẽ nhận một lỗi WSAECONNREFUSED . Tiếp theo, ta sử dụng hàm Accept để chấp nhận kết nối. virtual BOOL Accept(CAsyncSocket& rConnectedSocket, SOCKADDR* lpSockAdd = NULL, int* lpSockAddr = NULL); rConnectedSocket: Tham chiếu đến socket mới được lấy tự Client. lpSockAdd : Là một con trỏ đến cấu trúc SOCKADDR socket kết nối đến. Nếu lpSockAddr hoặc lpSocketAddrLen có giá trị là NULL thì sẽ không có thông tin nào về địa chỉ của socket vừa được kết nối được trả về. Mặc định là NULL. Tương tự như các phương thức ở trên, giá trị trả về của hàm này là khác 0 nếu hàm chương trình thực hiện thành công, ngược lại sẽ bằng 0. Mã lỗi sẽ được xác định thông qua hàm GetLastError.(xem chi tiết trong MSDN). Sau khi đã chấp nhận kết nối, ta có thể dùng các hàm Send, Receive để truyền và nhận thông điệp và hàm Close để đóng socket giống như đã làm ở Client. Ví dụ sau sẽ trình bày cách thức một server chấp nhận một kết nối vào: Các biến được sử dụng trong ví dụ này sẽ gồm 2 biến CSocket một để mở cổng và một để truyền dữ liệu (Trong thực tế, một cổng có thể cho phép nhiều client nối vào, khi đó vẫn chỉ có một CSocket để mở cổng nhưng sẽ có nhiều CSocket để truyền dữ liệu). CSocket skListen, skConnect; If(!skListen.Create(1111) || !skListen.Listen() || ! skListen.Accept(skConnect)) { cout<<”server socket bi loi”; exit(0); } else { //truyền thông điệp qua lại giữa client và server. char msg[1000]; int msg_len ; while(1); { //Nhận thông điệp từ Client skConnect.Receive(&msg_len, sizeof(msg_len)); //nhận chiều dài thông điệp. skConnect.Receive(msg,msg_len);//Nhận nội dung thông điệp. skConnect[msg_len] = 0; //Kết thúc chuỗi. //Gửi thông điệp đến Client skConnect.Send(&msg_len, sizeof(msg_len)); //Gửi chiều dài thông điệp. skConnect.Send(msg,msg_len);//Gửi nội dung thông điệp. } skConnect.Close(); } . phần tiếp theo chúng ta sẽ khảo sát những thành phần cơ bản của lớp CSocket hỗ trợ cho việc lập trình mạng. Client: Để có thể sử dụng được thư viện CSocket, cần phải làm hai công việc, một là. các phương thức ở trên, giá trị trả về của hàm này là khác 0 nếu hàm chương trình thực hiện thành công, ngược lại sẽ bằng 0. Mã lỗi sẽ được xác định thông qua hàm GetLastError.(xem chi tiết trong. thực sự đóng một socket, ta nên gọi hàm shutdown (). Chúng ta có thể trực tiếp hủy một socket bằng cách đóng nó, nhưng tốt hơn ta nên gọi hàm shutdown() trước tiên bởi vì điều này đảm bảo rằng:

Ngày đăng: 14/07/2014, 01:20

Từ khóa liên quan

Mục lục

  • Đóng Socket :

  • Sử dụng MFC:

    • Giới thiệu về lớp CSocket:

    • Client:

    • Server:

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan