#include <Winsock2.h>
#include <stdio.h>
#include <windows.h>
#include <string.h>
DWORD WINAPI RecvProc(
LPVOID lpParameter // thread data
);
struct RECVPARAM
{
SOCKET sock;
SOCKADDR_IN sockaddr;
};
void main()
{
WORD wVersionRequseted;
WSADATA wsaData;
int err;
wVersionRequseted = MAKEWORD(1, 1);
err = WSAStartup(wVersionRequseted, &wsaData);
if(err!=0)
{
return;
}
if(LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) !=1)
{
WSACleanup();
return;
}
SOCKET socketSrv = 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(6000);
bind(socketSrv, (SOCKADDR *)&addrSrv, sizeof(SOCKADDR));
listen(socketSrv, 5);
SOCKADDR_IN addrClient;
int len=sizeof(SOCKADDR);
HANDLE hRecvThread;
RECVPARAM *pRecvParam=new RECVPARAM;
printf("服务器启动\n");
while(1)
{
SOCKET sockConn = accept(socketSrv, (SOCKADDR*)&addrClient, &len);
pRecvParam->sock=sockConn;
pRecvParam->sockaddr = addrClient;
hRecvThread=CreateThread(NULL,0,RecvProc,(LPVOID)pRecvParam,0,NULL);
}
delete pRecvParam;
}
DWORD WINAPI RecvProc(
LPVOID lpParameter // thread data
)
{
char recvBuf[200];
memset(recvBuf,0 ,200);
SOCKET sockClient =((RECVPARAM*)lpParameter)->sock;
SOCKADDR_IN addrClient = ((RECVPARAM*)lpParameter)->sockaddr;
printf("%s 进入连接\n", inet_ntoa(addrClient.sin_addr));
while(TRUE)
{
if(!recv(sockClient, recvBuf, 200,0))
{
printf("%s 客户端断开连接\n", inet_ntoa(addrClient.sin_addr));
break;
}
if(0==strcmp(recvBuf, "abc"))
{
send(sockClient, "thank you!", strlen("thank you!"), 0);
closesocket(sockClient);
break;
}
printf("%s\n", recvBuf);
}
printf("线程终止\n");
return 0;
}
链接时需要包含ws2_32.lib库文件,对于VC6.0在菜单-工程-设置里面,或者在头文件下面添加:#pragma comment(lib,"ws2_32.lib")
如果在MFC中编写网络应用程序,需注意以下两点:
1. 在StdAfx.h头文件中包含 #include <Afxsock.h>, 这个头文件中包含了MFC封装后的套接字类,比如:CSocket和CAyncSocket,但是你也可以不使用这些类。
2. 在CXXApp类中的InitInstance函数中调用AfxSocketInit()函数,加载套接字库,也就是这个函数封装了WSAStartup函数来进行套接字的初始化,程序退出后MFC会自动调用WSACleanup函数。