实验一、二 TCP/UDP应用程序实现
一、实验目的和任务
1、掌握网络的基本应用。 2、掌握Socket编程。
3、掌握TCP和UDP的编程模型。
二、实验内容
实验一:
1、编写程序获得本机的主机名称和IP地址。 2、编写程序实现网络聊天(使用UDP+多线程)。 试验二:
3、编写程序实现网络传输文件(使用TCP套接字)。
三、实验步骤
[实验1步骤]
1、建立基于对话框的程序,参考界面。
2、参考代码如下: char szHostName[128]; WSADATA wsaData;
WSAStartup(MAKEWORD(1,1),&wsaData); if( gethostname(szHostName, 128) == 0 ) { m_HostName.SetWindowText(szHostName); struct hostent * pHost; int i; pHost = gethostbyname(szHostName); for( i = 0; pHost!= NULL && pHost->h_addr_list[i]!= NULL; i++ ) { char str[100]; char addr[20];
1
《TCP/IP网络编程》实验指导书
}
}
int j;
LPCSTR psz=inet_ntoa (*(struct in_addr *)pHost->h_addr_list[i]); m_IPAddr.AddString(psz);
WSACleanup();
[实验2步骤]
1、新建一个基于对话框的应用程序,参考界面如下。
2、建立对话框类的成员变量: sockaddr_in m_srv; sockaddr_in m_client; SOCKET m_socket; //和控件关联的变量
CListBox m_list; CString m_msg; CString m_destip; int m_destport;
CString m_hostip; int m_hostport;
3、建立监听开始,参考代码如下:
UpdateData(); m_srv.sin_family = PF_INET; m_srv.sin_addr.S_un.S_addr = inet_addr( m_hostip); m_srv.sin_port = htons( m_hostport ); m_socket = socket(AF_INET, SOCK_DGRAM, 0);
2
《TCP/IP网络编程》实验指导书
if( bind(m_socket,(struct sockaddr *)&m_srv,sizeof(m_srv)) !=0 ) { AfxMessageBox(\"绑定IP和端口失败!\"); return; } AfxBeginThread(thread,0,0,0,NULL);
4、建立线程处理函数,参考代码如下:(改函数在头文件中,UINT前加static) UINT thread(LPVOID v) { CChat_UdpDlg *dlg=(CChat_UdpDlg*) AfxGetApp()->GetMainWnd(); while(1) { CString str; char buff[128]={0}; int len = sizeof(dlg->m_client); int result = recvfrom(dlg->m_socket, buff, sizeof(buff), 0,0,0); str.Insert(0,buff); dlg->m_list.AddString(buff); } }
5、建立发送部分,参考代码如下:
UpdateData(); sockaddr_in dest; // 发送目标地址 dest.sin_family = PF_INET; dest.sin_addr.S_un.S_addr = inet_addr(m_destip); // 任何地址 dest.sin_port = htons( m_destport); m_list.AddString(m_msg); sendto(m_socket,(char*)m_msg.GetBuffer(0), m_msg.GetLength(), 0,
(sockaddr *)&dest, sizeof(sockaddr_in));
m_msg=_T(\"\"); UpdateData(FALSE);
6、初始化,在对话框的OnInitDialog函数中添加代码: WSADATA wsaData; WSAStartup(MAKEWORD(2,2),&wsaData);
7、给窗体添加OnClose()函数, void CNetChatDlg::OnClose() { // TODO: Add your message handler code here and/or call default
3
《TCP/IP网络编程》实验指导书
WSACleanup(); CDialog::OnClose(); }
[实验3步骤]
1、新建一个基于对话框的应用程序。
2、在对话框的OnInitDialog函数中添加代码:
WSADATA wsaData; WSAStartup(MAKEWORD(2,2),&wsaData);
然后,再添加给窗体OnClose()函数, void CFileTransDlg::OnClose() { // TODO: Add your message handler code here and/or call default WSACleanup(); CDialog::OnClose(); }
3、建立CListenSocket类:
(1)使用类向导建立CListenSocket,基类选择CSocket,在CListenSocket的头文件中添加:
#include \"afxsock.h\" class CFileTransDlg;
(2)添加Init成员函数,代码如下:
BOOL CListenSocket::Init(int port, CFileTransDlg *p) { m_Parent = p; if(Create(port)==FALSE) { AfxMessageBox(\"Server Socket Create Error\"); return FALSE; } if(Listen()==FALSE) { AfxMessageBox(\"Server Listen Error\"); return FALSE; } return TRUE; }
(3) 在CListenSocket类中添加数据成员:
4
《TCP/IP网络编程》实验指导书
CFileTransDlg *m_Parent;
(4)重载虚函数OnServerAccept(),代码如下: void CListenSocket::OnAccept(int nErrorCode) { m_Parent->ServerAccept(); CSocket::OnAccept(nErrorCode); }
4、建立CClientSocket类:
(1)使用类向导建立CListenSocket,基类选择CSocket,在CListenSocket的头文件中添加:
#include \"afxsock.h\" (2)添加数据成员:
CString m_path;
(3)重载虚函数OnReceive,代码如下
void CClientSocket::OnReceive(int nErrorCode) { char buff[1024]; char temp[13],temp2[7]; int i,step; step = Receive(buff,1024); for(i=0;i<13;i++) temp[i] = buff[i]; temp[12]='\\0'; for(i=0;i<7;i++) temp2[i] = buff[i]; temp2[6]='\\0'; if(strcmp(temp,\"MyFileName##\")==0)//文件开始 { CFileDialog dlg(FALSE); dlg.DoModal(); m_path = dlg.GetPathName(); CFile file(m_path, CFile::modeCreate); } else if(strcmp(temp2,\"FINISH\")==0)//文件结束 { AfxMessageBox(\"发送完毕\"); } else//文件内容
5
《TCP/IP网络编程》实验指导书
{ CFile file(m_path, CFile::modeReadWrite); file.SeekToEnd(); file.Write(buff,step); } CSocket::OnReceive(nErrorCode); }
1、 修改对话框界面,如下图所示,并关联成员变量
CString m_strIP; int m_nPort;
6、在对话框类头文加添加:
#include \"ListenSocket.h\" #include \"ClientSocket.h\" 7、在对话框类中添加成员变量
int m_ConnectCount; CListenSocket m_pListenSocket; CClientSocket *m_pConnectSocket[10]; CClientSocket m_ClientSocket; 8、为对话框添加监听代码如下: void CFileTransDlg::OnListen() { m_pListenSocket.Init(m_nPort,this); }
9、为对话框添加发送代码如下: void CFileTransDlg::OnSend() { m_ClientSocket.Create(); int u = m_ClientSocket.Connect(m_strIP,m_nPort); char buff[1024]; CFileDialog dlg(TRUE); dlg.DoModal();
6
《TCP/IP网络编程》实验指导书
CString path = dlg.GetPathName(); CString name = dlg.GetFileName(); CFile file(path, CFile::modeRead); name = \"MyFileName##\" + name; m_ClientSocket.Send(name,12); int count, step=0; for(count=0; count 11、本实现仍然有部分问题,请你改正。 四、思考问题 1、写出第一个实验中获得IP地址和通过IP地址获得机器名的两个函数的原形。 2、如何重载CSocket中的虚函数OnAccept和OnReceive? 3、写出使用CSocket对象m_listen建立监听的过程? 4、写出设置sockaddr_in类型的变量srv,假设地址为192.168.1.1,端口为8888 5、使用Windows Socket API编程,启动和释放如何处理? 7 因篇幅问题不能全部显示,请点此查看更多更全内容