intTypePromotion=1
zunia.vn Tuyển sinh 2024 dành cho Gen-Z zunia.vn zunia.vn
ADSENSE

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

Chia sẻ: Vu Dinh Hiep | Ngày: | Loại File: DOC | Số trang:8

125
lượt xem
14
download
 
  Download Vui lòng tải xuống để xem tài liệu đầy đủ

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. ...

Chủ đề:
Lưu

Nội dung Text: Lập trình mạng bằng pocket PC-part 7

  1. Đó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.
  2. 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 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.
  3. 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
  4. 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
  5. While(1) { cout
  6. 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 sẽ nhận một lỗi = 5) thì client 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ẽ
  7. 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
  8. 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. //Kết thúc chuỗi. skConnect[msg_len] = 0; //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(); }
ADSENSE

CÓ THỂ BẠN MUỐN DOWNLOAD

 

Đồng bộ tài khoản
2=>2