socket 编程通信实例:
TCPserver:
public:
BOOL bStatus ;
HANDLE hThread ;
friend DWORD WINAPI ServerThread ( LPVOID lParam ) ;
BOOL CTCPServerDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
this->bStatus = TRUE ;
this->hThread = CreateThread ( NULL, 0, ServerThread, this, NULL, NULL ) ;
if ( this->hThread == NULL )
{
this->MessageBox ( L"创建服务线程失败!" ) ;
this->bStatus = FALSE ;
}
return TRUE; // 除非将焦点设置到控件,否则返回TRUE
}
DWORD WINAPI ServerThread ( LPVOID lParam )
{
// 窗体对象指针
CTCPServerDlg* pDlg = (CTCPServerDlg*)lParam ;
// 初始化WinSock
DWORD dwErrorCode = 0 ;
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR)
{
OutputMessage ( L"初始化失败!", GetLastError() ) ;
return 0 ;
}
// 创建套接字
SOCKET LocalSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (LocalSocket == INVALID_SOCKET )
{
OutputMessage ( L"创建socket失败!", GetLastError() ) ;
return 0;
}
// 取得本地地址信息
char szHostName[DEF_BUF_SIZE] = {0} ;
gethostname ( szHostName, DEF_BUF_SIZE ) ;
hostent* pHost = gethostbyname ( szHostName ) ;
if ( pHost == NULL )
return FALSE ;
sockaddr_in SrvAddr;
SrvAddr.sin_family = AF_INET;
SrvAddr.sin_port = htons(12345);
memcpy ( &(SrvAddr.sin_addr.s_addr), pHost->h_addr_list[0], pHost->h_length ) ;
// 绑定地址信息到套接字
if ( bind ( LocalSocket, (SOCKADDR*)&SrvAddr, sizeof(SOCKADDR) ) == SOCKET_ERROR )
{
OutputMessage ( L"绑定地址信息失败!", GetLastError() ) ;
return 0;
}
// 监听
if ( listen(LocalSocket,SOMAXCONN) == SOCKET_ERROR )
{
OutputMessage ( L"监听失败!", GetLastError() ) ;
return 0;
}
while ( TRUE )
{
int len = sizeof(SOCKADDR) ;
sockaddr_in ConnAddr ;
// 接受连接
SOCKET ConnSock = accept ( LocalSocket, (SOCKADDR*)&ConnAddr, &len ) ;
if ( ConnSock == INVALID_SOCKET )
{
OutputMessage ( L"接受连接失败!", GetLastError() ) ;
continue ;
}
// 接收数据
char szData[DEF_BUF_SIZE] = {0} ;
int nRecvSize = recv ( ConnSock, szData, DEF_BUF_SIZE, 0 ) ;
if ( nRecvSize <= 0 )
{
OutputMessage ( L"接收数据错误!", GetLastError() ) ;
continue ;
}
// 服务器所提供的服务,这里是简单的加法运算
sscanf ( szData, "%d %d", &pDlg->nDataA, &pDlg->nDataB ) ;
pDlg->nDataC = pDlg->nDataA + pDlg->nDataB ;
pDlg->SetDlgItemInt ( IDC_DATA_A, pDlg->nDataA ) ;
pDlg->SetDlgItemInt ( IDC_DATA_B, pDlg->nDataB ) ;
pDlg->SetDlgItemInt ( IDC_DATA_C, pDlg->nDataC ) ;
// 发送数据
int nSendSize = send ( ConnSock, (char*)&pDlg->nDataC, sizeof(UINT), 0 ) ;
if ( nSendSize <= 0 )
{
OutputMessage ( L"发送数据错误!", GetLastError() ) ;
continue ;
}
closesocket ( ConnSock ) ;
}
closesocket ( LocalSocket ) ;
WSACleanup();
return 0 ;
}
TCPclient:
public:
afx_msg void OnBnClickedSend();
BOOL CTCPClientDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
// 取得原始服务地址
WSADATA wsaData;
WSAStartup(MAKEWORD(2,2), &wsaData) ;
in_addr addr ;
char szHostName[DEF_BUF_SIZE] = {0} ;
gethostname ( szHostName, DEF_BUF_SIZE ) ;
hostent* pHost = gethostbyname ( szHostName ) ;
if ( pHost )
{
memcpy ( &addr, pHost->h_addr_list[0], pHost->h_length ) ;
::SetDlgItemTextA ( this->m_hWnd, IDC_IP, inet_ntoa ( addr ) ) ;
}
return TRUE; // 除非将焦点设置到控件,否则返回TRUE
}
void CTCPClientDlg::OnBnClickedSend()
{
// 初始化WinSock
DWORD dwErrorCode = 0 ;
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR)
{
OutputMessage ( L"初始化失败!", GetLastError() ) ;
return ;
}
// 连接原始服务器
SOCKET LocalSock = socket ( AF_INET, SOCK_STREAM, IPPROTO_TCP ) ;
if ( LocalSock == INVALID_SOCKET )
{
OutputMessage ( L"创建socket失败!", GetLastError() ) ;
return ;
}
// 设置超时信息
int nTimeOut = 3000 ;
::setsockopt(LocalSock,SOL_SOCKET,SO_RCVTIMEO,(char *)&nTimeOut,sizeof(int) ) ;
// 取得原始服务地址
char szSrvIp[DEF_BUF_SIZE] = {0} ;
::GetDlgItemTextA ( this->m_hWnd, IDC_IP, szSrvIp, DEF_BUF_SIZE ) ;
sockaddr_in RemoteAddr;
RemoteAddr.sin_family = AF_INET;
RemoteAddr.sin_port = htons(12345);
RemoteAddr.sin_addr.s_addr = inet_addr ( szSrvIp ) ;
// 连接服务器
if ( connect ( LocalSock, (SOCKADDR*)&RemoteAddr, sizeof(SOCKADDR) ) == SOCKET_ERROR )
{
OutputMessage ( L"连接失败!", GetLastError() ) ;
return ;
}
// 发送请求(数据A和数据B)
char szData[DEF_BUF_SIZE] = {0} ;
sprintf ( szData, "%d %d", this->nDataA, this->nDataB ) ;
int nSendSize = send ( LocalSock, szData, DEF_BUF_SIZE, 0 ) ;
if ( nSendSize <= 0 )
{
OutputMessage ( L"发送数据错误!", GetLastError() ) ;
return ;
}
// 接收服务器处理结果(数据C)
int nRecvSize = recv ( LocalSock, (char*)&this->nDataC, sizeof(UINT), 0 ) ;
if ( nRecvSize <= 0 )
{
OutputMessage ( L"接受数据错误!", GetLastError() ) ;
return ;
}
// 更新界面信息
this->UpdateData ( FALSE ) ;
// 关闭套接字句柄
closesocket ( LocalSock ) ;
WSACleanup();
}
UDP server:
BOOL CUDPServerDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
this->hThread = CreateThread ( NULL, 0, ServerThread, this, 0, NULL ) ;
return TRUE; // 除非将焦点设置到控件,否则返回TRUE
}
DWORD WINAPI ServerThread ( LPVOID lParam )
{
CUDPServerDlg* pDlg = (CUDPServerDlg*)lParam ;
// 初始化WinSock
DWORD dwErrorCode = 0 ;
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR)
{
OutputMessage ( L"初始化失败!", GetLastError() ) ;
return 0;
}
// 创建套接字
SOCKET LocalSock = socket ( AF_INET, SOCK_DGRAM, IPPROTO_UDP ) ;
if ( LocalSock == INVALID_SOCKET )
{
OutputMessage ( L"创建socket失败!", GetLastError() ) ;
return 0;
}
// 取得本地地址信息
char szHostName[DEF_BUF_SIZE] = {0} ;
gethostname ( szHostName, DEF_BUF_SIZE ) ;
hostent* pHost = gethostbyname ( szHostName ) ;
if ( pHost == NULL )
return 0 ;
sockaddr_in SrvAddr, ClientAddr ;
SrvAddr.sin_family = AF_INET;
SrvAddr.sin_port = htons(34567);
memcpy ( &(SrvAddr.sin_addr.s_addr), pHost->h_addr_list[0], pHost->h_length ) ;
if ( bind ( LocalSock, (sockaddr*)&SrvAddr, sizeof(sockaddr) ) == SOCKET_ERROR )
{
OutputMessage ( L"绑定失败!", GetLastError() ) ;
return 0;
}
// 发送数据(最多字节)
char szData[DEF_BUF_SIZE] = {0} ;
while ( TRUE )
{
int len = sizeof(sockaddr) ;
int nSendSize = recvfrom ( LocalSock, szData, DEF_BUF_SIZE, 0, (sockaddr*)&ClientAddr, &len ) ;
if ( nSendSize <= 0 )
{
OutputMessage ( L"接收数据错误!", GetLastError() ) ;
}
else
::SetDlgItemTextA ( pDlg->m_hWnd, IDC_DATA, szData ) ;
}
// 关闭套接字句柄
closesocket ( LocalSock ) ;
WSACleanup();
return 0 ;
}
UDPclient:
void CUDPClientDlg::OnBnClickedSend()
{
// 初始化WinSock
DWORD dwErrorCode = 0 ;
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR)
{
OutputMessage ( L"初始化失败!", GetLastError() ) ;
return ;
}
// 创建套接字
SOCKET LocalSock = socket ( AF_INET, SOCK_DGRAM, IPPROTO_UDP ) ;
if ( LocalSock == INVALID_SOCKET )
{
OutputMessage ( L"创建socket失败!", GetLastError() ) ;
return ;
}
// 取得服务地址
char szSrvIp[DEF_BUF_SIZE] = {0} ;
::GetDlgItemTextA ( this->m_hWnd, IDC_SRV_IP, szSrvIp, DEF_BUF_SIZE ) ;
sockaddr_in SrvAddr;
SrvAddr.sin_family = AF_INET;
SrvAddr.sin_port = htons(34567);
SrvAddr.sin_addr.s_addr = inet_addr ( szSrvIp ) ;
// 发送数据(最多字节)
char szData[DEF_BUF_SIZE] = {0} ;
::GetDlgItemTextA ( this->m_hWnd, IDC_DATA, szData, DEF_BUF_SIZE ) ;
int nSendSize = sendto ( LocalSock, szData, DEF_BUF_SIZE, 0, (sockaddr*)&SrvAddr, sizeof(sockaddr) ) ;
if ( nSendSize <= 0 )
{
OutputMessage ( L"发送数据错误!", GetLastError() ) ;
return ;
}
// 关闭套接字句柄
closesocket ( LocalSock ) ;
WSACleanup();
}