1. Trang chủ
  2. » Công Nghệ Thông Tin

Networking and Network Programming 2 TCP/IP phần 9 ppt

33 252 1

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

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Networking and Network Programming 2 Tcp/Ip Phần 9 Ppt
Trường học University of Information Technology
Chuyên ngành Networking and Network Programming
Thể loại Bài giảng
Năm xuất bản 1994
Thành phố Ho Chi Minh City
Định dạng
Số trang 33
Dung lượng 238,21 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Chapter 14 ■ Sample Applications 273P2/Vol.6 Programming WinSock #30594-1 tullis 11.14.94 CH14 LP #3 LPVOID pDataWritten; // pointer to data that is completely written LPVOID pDataRead

Trang 1

Part IVProgramming with the WinSock Class Library

// get pointer to list box used for status messages

CListBox *plb = (CListBox *)GetDlgItem(IDC_LIST_STATUS);

// initialize the WinSock object

m_pWinSock = new CWinSock;

// initialize the stream socket object

m_pStreamSrv = new CStreamSocket(this, WM_USER_STREAMSRV);

/////////////////////////////////////////////////////////////////////////////// CMainView::OnStreamSrv()

// get pointer to list box used for status messages

CListBox *plb = (CListBox *)GetDlgItem(IDC_LIST_STATUS);

switch (wParam)

{

Listing 14.6 continued

Trang 2

Chapter 14Sample Applications 273

P2/Vol.6 Programming WinSock #30594-1 tullis 11.14.94 CH14 LP #3

LPVOID pDataWritten; // pointer to data that is completely written

LPVOID pDataRead; // pointer to data just read

int nLen; // length

char pszMessage[1000];// informational message

SOCKADDR_IN sin; // Internet address of client

IN_ADDR in; // IP address of client

int nStatus; // error status

// get pointer to list box used for status messages

CListBox *plb = (CListBox *)GetDlgItem(IDC_LIST_STATUS);

Trang 3

Part IVProgramming with the WinSock Class Library

// echo the data back to the sender

if (m_pStream->Write(nLen, pDataRead) != CWINSOCK_NOERROR)

Trang 4

Chapter 14Sample Applications 275

P2/Vol.6 Programming WinSock #30594-1 tullis 11.14.94 CH14 LP #3

Stream Echo Client CSECLNT

The stream echo client, CSECLNT, is a reimplementation of the SECLIENT program

described in Chapter 8 It uses a CFormView -derived object as its main interface The

header file for the CMainView object is shown in Listing 14.7 Its implementation is shown

in Listing 14.8 This object performs most of the work for the CSECLNT application.

OnInitialUpdate() is called soon after the object is created This function is

respon-sible for starting the WinSock subsystem, creating a client stream socket, prompting

for the host name or IP address of the CSESRV stream echo server, and setting a

five-second interval timer used for data writes When the server accepts the client’s

connection request on port 2000, O n S t r e a m ( ) is called with w P a r a m set to

CWINSOCK_YOU_ARE_CONNECTED When the five-second timer goes off, OnTimer() is called.

If there is no data waiting to be sent—denoted by the first byte of the outgoing buffer

m_pszBuf containing a NULL —an outgoing data stream is formatted and the stream socket

object’s Write() member function is called to send data to the designated server When

the write completes, OnStream() is called with wParam set to CWINSOCK_DONE_WRITING

The first byte of m_pszBuf is set to NULL to indicate that the buffer is available The

CMainView object is continually waiting for its previously sent data to be echoed back.

When data arrives on the stream socket, OnStream() is triggered with wParam set to

CWINSOCK_DONE_READING The data is read and the read buffer is then freed When the

client application is closed, CMainView ’s destructor is called, destroying the stream socket

object and shutting down the WinSock subsystem.

Listing 14.7 MAINVIEW.H for CSECLNT.

// mainview.h : header file

#include “cwinsock.h” // Windows Sockets classes

class CMainView : public CFormView

{

DECLARE_DYNCREATE(CMainView)

private:

CWinSock * m_pWinSock; // WinSock sub-system startup/.shutdown

CStreamSocket * m_pStream; // Stream socket to receive from

char m_pszBuf[100]; // buffer to send

char m_pszServer[100]; // host name or IP address of stream server

continues

Trang 5

Part IVProgramming with the WinSock Class Library

enum { IDD = IDD_DIALOG_MAIN };

// NOTE: the ClassWizard will add data members here

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

virtual void OnInitialUpdate();

// Generated message map functions

//{{AFX_MSG(CMainView)

afx_msg LONG OnStream(WPARAM wParam, LPARAM lParam);

afx_msg void OnTimer(UINT nIDEvent);

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

/////////////////////////////////////////////////////////////////////////////

#define WM_USER_STREAM (WM_USER + 1)

Listing 14.8 MAINVIEW.CPP for CSECLNT.

// mainview.cpp : implementation file

IMPLEMENT_DYNCREATE(CMainView, CFormView)

Listing 14.7 continued

Trang 6

Chapter 14Sample Applications 277

P2/Vol.6 Programming WinSock #30594-1 tullis 11.14.94 CH14 LP #3

// start the timer used to trigger the socket writes

SetTimer(1, 5000, NULL); // 5 second timer

// get pointer to list box used for status messages

CListBox *plb = (CListBox *)GetDlgItem(IDC_LIST_STATUS);

// initialize the WinSock object

m_pWinSock = new CWinSock;

Trang 7

Part IVProgramming with the WinSock Class Library

278

P2/Vol.6 Programming WinSock #30594-1 tullis 11.14.94 CH14 LP #3

plb->InsertString(0, “WinSock initialization failed”);

delete m_pWinSock;

m_pWinSock = NULL;

return;

}

// prompt for server information

// (host name or IP address of stream server)

// initialize the stream socket object

m_pStream = new CStreamSocket(this, WM_USER_STREAM);

/////////////////////////////////////////////////////////////////////////////

Listing 14.8 continued

Trang 8

Chapter 14Sample Applications 279

P2/Vol.6 Programming WinSock #30594-1 tullis 11.14.94 CH14 LP #3

LPVOID pDataWritten; // pointer to data that is completely written

LPVOID pDataRead; // pointer to data just read

int nLen; // length

char pszMessage[1000];// informational message

// get pointer to list box used for status messages

CListBox *plb = (CListBox *)GetDlgItem(IDC_LIST_STATUS);

Trang 9

Part IVProgramming with the WinSock Class Library

static int nSendCount = 1; // used to generate unique message

char pszMessage[1000]; // informational message

// make sure we are not sending out of a bad stream socket

if (m_pStream == NULL)

return;

// get pointer to list box used for status messages

CListBox *plb = (CListBox *)GetDlgItem(IDC_LIST_STATUS);

// send the buffer unless the previous send hasn’t completed yet

if ((*m_pszBuf) == ‘\0’)

{

wsprintf(m_pszBuf, “Hello %d”, nSendCount);

++nSendCount;

// be sure to send terminating NULL character

if (m_pStream->Write(lstrlen(m_pszBuf) + 1, m_pszBuf) != CWINSOCK_NOERROR)

Running the Stream Echo Server and Client

Following is a sample sequence of events that occur when the stream echo client and server are run:

1 Run CSESRV.

2 Run CSECLNT on the same or a different computer It prompts for the host name or IP address CSESRV is using A connection to the server is attempted.

3 CSESRV’s CMainView::OnStreamSrv() is called with the

CWINSOCK_READY_TO_ACCEPT_CONNECTION event and, if the m_pStream socket is not yet connected to a client, a connection attempt is made.

4 When the server’s connection accept succeeds, OnStream() is called with wParam

set to CWINSOCK_YOU_ARE_CONNECTED

5 CDECLNT’s CMainView::OnStream() is also called with the

CWINSOCK_YOU_ARE_CONNECTED event.

Listing 14.8 continued

Trang 10

Chapter 14Sample Applications 281

P2/Vol.6 Programming WinSock #30594-1 tullis 11.14.94 CH14 LP #3

6 In five seconds, the timer will trigger in CSECLNT, causing

CMainView::OnTimer() to get called No bytes are waiting to be sent yet, so the

outgoing buffer is filled and written to the connected server.

7 CMainView::OnStream() is called in CSECLNT with a CWINSOCK_DONE_WRITING

notice The outgoing buffer is then marked as unused so that it may be used

with the next triggering of CMainView::OnTimer()

8 CMainView::OnStream() is called in CSESRV with a CWINSOCK_DONE_READING

notice The data is read and immediately echoed back to the client.

9 CMainView::OnStream() is called in CSESRV with a CWINSOCK_DONE_WRITING

notice The data is then freed.

10 CMainView::OnStream() is called in CSECLNT with a CWINSOCK_DONE_READING

notice The echoed data is read and then freed.

11 Another timer goes off in CSECLNT and the process repeats.

If CSECLNT is closed first, CMainView::OnStream() is called in CSESRV with a

CWINSOCK_LOST_CONNECTION notice If CSESRV is closed first, CMainView::OnStream()

is called in CSECLNT with a CWINSOCK_LOST_CONNECTION notice.

Summary

This chapter demonstrates the use of the CWinSock , CDatagramSocket , and CStreamSocket

objects These objects are designed to make socket programming easier for you.

It is hoped that the comparison of these sample programs with those of Chapter 8 proves

that the design goals of the WinSock class library, described in Chapter 9, are met A

comparison also reveals one of the limitations of the CDatagramSocket and CStreamSocket

objects These objects don’t have the capability of letting the WinSock subsystem

as-sign an unused port to a server socket Instead, the port must be specified in terms of its

port number or service name, in this case to port number 2000.

The next chapter uses the WinSock class library objects in a sample client-server

data-base environment.

Trang 11

Chapter 15Practical Client/Server Database Application 283

p2/v6 SN8 Programming WinSock #30594-1 tullis 11.14.94 CH15 LP #3

15

Practical Client/ Server Database Application

Practical Client/ Server Database Application

Trang 12

p2/v6 SN8 Programming WinSock #30594-1 tullis 11.14.94 CH15 LP #3

Part IVProgramming with the WinSock Class Library

The client (INICLNT) and server (INISRV) use the CDatagramSocket and CStreamSocket

objects In previous chapters, the server examples could handle only one client tion at a time This server is more realistic in that it can service several clients simulta- neously The server is implemented as a Multiple Document Interface application in which each window represents a client connection The client is a simple Single Docu- ment Interface application A stream socket connection is used to transmit database commands and responses between the client and server A datagram socket is used to

connec-send a heartbeat message from the server to the client The heartbeat is a block of data

that is sent between the client and server to let each know that the other side is still tive and able to communicate This heartbeat allows the client program to show a visual indication of the client/server link status.

ac-The “database” in this example uses Windows’ built-in INI file facility An INI file is used to maintain configuration information for an application An example INI file is shown below:

[boot] is called the section 386grabber is an example of an entry or key ajvga.3gr is its

value The GetPrivateProfileString() and WritePrivateProfileString() SDK tions are used to read and write an INI file string value, respectively.

func-Client INICLNT

The client application, INICLNT, uses a CFormView -derived object as its main face The header file for the CMainView object is shown in Listing 15.1, which appears later in this section Its implementation is shown in Listing 15.2, which also appears later in this section This object performs most of the work for the INICLNT applica- tion OnInitialUpdate() is called soon after the object is created This function is re- sponsible for starting the WinSock subsystem, creating a client stream socket, creating

inter-a server dinter-atinter-agrinter-am socket for the heinter-artbeinter-at, prompting for the host ninter-ame or IP inter-address

of the INISRV server, and setting a timer interval used for the heartbeats When the

Trang 13

Chapter 15Practical Client/Server Database Application 285

p2/v6 SN8 Programming WinSock #30594-1 tullis 11.14.94 CH15 LP #3

server accepts the client’s connection request, OnStream() is called with wParam set to

CWINSOCK_YOU_ARE_CONNECTED

Command Identifier

The user enters the read or write parameters into the appropriate fields and then selects

either the Read or Write button, triggering O n C l i c k e d B u t t o n R e a d ( ) or

OnClickedButtonWrite() , respectively These functions format the database command

and call FillAndSendDBCmd() , which assigns a unique identifier to the database

com-mand and sends it to the server The database comcom-mand has the following structure:

typedef struct tagDBCOMMAND

{

int nID; // database command identifier

int nCommand; // database command

char szFile[DBBUFSIZE]; // INI file

char szSection[DBBUFSIZE]; // section of INI file

char szEntry[DBBUFSIZE]; // entry within section of INI file

char szValue[DBBUFSIZE]; // value of entry within section of INI file

} DBCOMMAND, FAR * LPDBCOMMAND;

ClassWizard is used to limit the number of bytes that may be entered into the data entry

fields of CMainView This limit is set to 40 to match the DBBUFSIZE value used in the

preceding DBCOMMAND definition.

Possible commands for the client are DB_READ and DB_WRITE A unique identifier is

as-signed because there could be multiple outstanding database requests; the client and

server operate totally asynchronously The identifier may be used to correlate the

com-mand and its asynchronous response Once the comcom-mand is successfully sent, OnStream()

is called with wParam set to CWINSOCK_DONE_WRITING When the server is done processing

the database command, it sends a response to the client, triggering OnStream() with wParam

set to CWINSOCK_DONE_READING The HandleRead() function processes the database

re-sponse sent by the server.

Heartbeat Link Status Indicator

This application has a timer that’s used to keep track of missing heartbeat messages.

The OnDatagram() function handles reception of the heartbeats sent from the connected

server If one heartbeat message is missed, the traffic light status indicator changes to a

yellow light Missing two or more heartbeats causes the light to turn red If the

heart-beats are received without fail, the light remains green This provides for a visual cue as

to the state of the server.

When CMainView ’s destructor is called, the stream and datagram sockets are destroyed

and the WinSock subsystem is shut down.

Trang 14

p2/v6 SN8 Programming WinSock #30594-1 tullis 11.14.94 CH15 LP #3

Part IVProgramming with the WinSock Class Library

286

Listing 15.1 MAINVIEW.H for INICLNT.

// mainview.h : header file

//

/////////////////////////////////////////////////////////////////////////////// CMainView form view

CWinSock * m_pWinSock; // WinSock sub–system startup/.shutdown

CStreamSocket * m_pStream; // Stream socket to receive from

CDatagramSocket * m_pDatagram; // Datagram socket to receive heartbeat

char m_pszServer[100]; // host name or IP address of stream server int m_nHeartbeat; // heartbeat count

HICON m_hRed, m_hYellow, m_hGreen; // link status icons

void HandleRead();

void FillAndSendDBCmd(LPDBCOMMAND pdb, LPCSTR szFile,

LPCSTR szSection, LPCSTR szEntry, LPCSTR szValue = NULL);

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

virtual void OnInitialUpdate();

// Generated message map functions

//{{AFX_MSG(CMainView)

afx_msg LONG OnStream(WPARAM wParam, LPARAM lParam);

Trang 15

Chapter 15Practical Client/Server Database Application 287

p2/v6 SN8 Programming WinSock #30594-1 tullis 11.14.94 CH15 LP #3

afx_msg LONG OnDatagram(WPARAM wParam, LPARAM lParam);

afx_msg void OnTimer(UINT nIDEvent);

afx_msg void OnClickedButtonRead();

afx_msg void OnClickedButtonWrite();

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

/////////////////////////////////////////////////////////////////////////////

#define WM_USER_STREAM (WM_USER + 1)

#define WM_USER_DATAGRAM (WM_USER + 2)

Listing 15.2 MAINVIEW.CPP for INICLNT.

// mainview.cpp : implementation file

Trang 16

p2/v6 SN8 Programming WinSock #30594-1 tullis 11.14.94 CH15 LP #3

Part IVProgramming with the WinSock Class Library

// start the timer used to keep track of heartbeats

SetTimer(1, HEARTBEAT_DELAY, NULL);

// get pointer to list box used for status messages

CListBox *plb = (CListBox *)GetDlgItem(IDC_LIST_STATUS);

// initialize the WinSock object

Listing 15.2 continued

Ngày đăng: 13/08/2014, 22:21

TỪ KHÓA LIÊN QUAN