客户端程序:
// 下载基础信息
void CTcpClientDlg::OnBnClickedBtnDownload()
{
// TODO: 在此添加控件通知处理程序代码
WSADATA wsaData;
int err;
// 1、加载套接字库
err = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (err != 0)
{
MessageBox(_T("加载套接字库失败!"));
return;
}
if (LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2) {
WSACleanup( );
MessageBox(_T("WinSock库不支持2.2版本!"));
return;
}
// 2、创建套接字
SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(9996); // 需要网络地址序
// 3、向服务器发出连接请求
err = connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));
if (err == SOCKET_ERROR)
{
CString strErr;
strErr.Format(_T("连接失败:%s"), WSAGetLastError());
MessageBox(strErr);
return;
}
// 4、和服务器端进行通讯
char recvBuf[100];
recv(sockClient, recvBuf, 100, 0);
printf_s("%s\n", recvBuf);
send(sockClient, "this is hero...", strlen("this is hero...") + 1, 0);
// 5、关闭套接字
closesocket(sockClient);
// 6、关闭加载的套接字库
WSACleanup();
}
服务端程序:
// 辅助线程处理函数
BOOL bStart = FALSE;
DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
WORD wVersionRequested;
WSADATA wsaData;
int iResult = 0;
wVersionRequested = MAKEWORD(2, 2);
// 1、初始化Windows Socket 2.2
iResult = WSAStartup(wVersionRequested, &wsaData);
if (iResult != NO_ERROR)
{
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
AfxMessageBox(_T("初始化套接字失败!"));
return 0;
}
/* Confirm that the WinSock DLL supports 2.2.*/
/* Note that if the DLL supports versions greater */
/* than 2.2 in addition to 2.2, it will still return */
/* 2.2 in wVersion since that is the version we */
/* requested. */
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE( wsaData.wVersion ) != 2)
{
WSACleanup( );
AfxMessageBox(_T("WinSock库不支持2.2版本!"));
return 0;
}
// 2、创建套接字
SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0);
if (INVALID_SOCKET == sockSrv)
{
AfxMessageBox(_T("创建套接字!"));
WSACleanup( );
return 0;
}
// 3、绑定套接字到一个IP地址和一个端口上
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY); // htonl将IP地址转换为网络格式
addrSrv.sin_family = AF_INET;
// 要使用1024以上的端口号
addrSrv.sin_port = htons(9996);
// 绑定到一个本地地址和端口上
iResult = bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(addrSrv));
if (iResult == SOCKET_ERROR)
{
AfxMessageBox(_T("绑定失败!"));
iResult = closesocket(sockSrv);
if (iResult == SOCKET_ERROR)
{
AfxMessageBox(_T("closesocket function failed with error %d\n"), WSAGetLastError());
}
WSACleanup();
return 0;
}
// 4、将套接字设置为监听模式等待连接请求
// 参数2:等待连接队列的最大长度
if (listen(sockSrv, 5) == SOCKET_ERROR)
{
wprintf(L"listen function failed with error: %d\n", WSAGetLastError());
}
SOCKADDR_IN addrClient;
int len = sizeof(SOCKADDR);
while(bStart)
{
// 5、请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept())
// 请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字
SOCKET sockConn = accept(sockSrv, (SOCKADDR*)&addrClient, &len);
char sendBuf[100];
sprintf_s(sendBuf, "Welcome %s to here!", inet_ntoa(addrClient.sin_addr));
CString str;
str.Format(_T("%s:"), inet_ntoa(addrClient.sin_addr));
// 6、用返回的套接字和客户端进行通信(send()/recv())
send(sockConn, sendBuf, strlen(sendBuf) + 1, 0);
char recvBuf[100];
recv(sockConn, recvBuf, 100, 0);
printf("%s\n",recvBuf);
// 关闭套接字
iResult = closesocket(sockConn);
if (iResult == SOCKET_ERROR)
{
AfxMessageBox(_T("closesocket function failed with error %d\n"), WSAGetLastError());
WSACleanup();
return 0;
}
// 7、返回,等待另一连接请求;
}
closesocket(sockSrv);
WSACleanup();
return 0;
}