最近在用Socket,不是很明白,但是总算是实现了socket传信息。现在把代码贴在这里:
这是一段MFC中的代码:
服务器端接受数据的代码:
static
DWORD WINAPI RunSocket(LPVOID lpvoid);
int CSocketAppView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == - 1 )
return - 1 ;
// 创建一个线程,用于接收数据。该线程执行的是方法RunSocket
DWORD nThread;
HANDLE nServerThread = CreateThread(NULL,NULL,RunSocket, this , 0 , & nThread); // 这是很重要的一个线程
CloseHandle(nServerThread);
// TODO: Add your specialized creation code here
return 0 ;
}
// 接收数据的方法
int RecvData( const SOCKET hClientSocket, char * szBuf, const int & iMaxBufSize);
DWORD WINAPI CSocketAppView::RunSocket(LPVOID lpvoid)
{
WORD wVersionRequested;
WSADATA wsaData;
char szBuf[ 1024 ];
wVersionRequested = MAKEWORD( 2 , 2 );
int iError = WSAStartup(wVersionRequested, & wsaData );
if ( iError != 0 )
.{
AfxMessageBox(TEXT( " 创建服务器端Socket初始化失败! " ));
return - 1 ;
}
if (LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 )
{
AfxMessageBox(TEXT( " 创建服务器端Socket初始化后失败! " ));
WSACleanup();
return - 1 ;
}
SOCKET hServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if ( hServerSocket == INVALID_SOCKET )
...{
AfxMessageBox(TEXT( " 创建服务器端Socket创建失败! " ));
return - 1 ;
}
// 套接字地址
struct sockaddr_in serverTcpAddr;
serverTcpAddr.sin_family = AF_INET; // 流式套接字
serverTcpAddr.sin_port = htons( 3001 ); // 端口号
serverTcpAddr.sin_addr.s_addr = inet_addr( " 127.0.0.1 " ); // IP号
// 指定本地地址
iError = bind(hServerSocket, (SOCKADDR * ) & serverTcpAddr, sizeof (serverTcpAddr));
if (iError != 0 )
{
int errorNo = WSAGetLastError();
if (errorNo == 10048 )
{
AfxMessageBox(TEXT( " 绑定失败!您的地址已经被占用! " ));
}
AfxMessageBox(TEXT( " 绑定失败! " ));
return - 1 ;
}
// 监听连接: 允许5个排队请求
iError = listen(hServerSocket, 5 );
if (iError != 0 )
{
AfxMessageBox(TEXT( " 监听失败! " ));
return - 1 ;
}
struct sockaddr_in clientTcpAddr;
SOCKET hClientSocket;
int iAddrSize = sizeof (clientTcpAddr);
while ( true )
{
hClientSocket = accept(hServerSocket, (SOCKADDR * ) & clientTcpAddr, & iAddrSize);
if (hClientSocket == INVALID_SOCKET)
{
AfxMessageBox(TEXT( " 获取数据失败! " ));
return - 1 ;
}
int iBytesReceived;
do
{
iBytesReceived = RecvData(hClientSocket, szBuf, 1024 );
if (iBytesReceived == SOCKET_ERROR)
{
int error = GetLastError();
CString e;
e.Format( " %d " , error);
e = " 遇到错误,错误代号: " + e;
AfxMessageBox(e);
break ;
}
if (iBytesReceived != 0 )
{
char szGetRec[ 16 ];
memcpy(szGetRec, szBuf, iBytesReceived);
AfxMessageBox(szGetRec);
}
/**//*
if (szBuf == "000")
{
exit(1);
} */
} while (iBytesReceived != 0 );
closesocket(hClientSocket);
}
AfxMessageBox(TEXT( " 服务器端Socket设置成功! " ));
}
int RecvData( const SOCKET hClientSocket, char * szBuf, const int & iMaxBufSize)
{
int iError;
iError = recv(hClientSocket, szBuf, iMaxBufSize, 0 );
if (iError == 0 )
{
return 0 ;
}
else if (iError == SOCKET_ERROR)
{
return SOCKET_ERROR;
}
return iError;
}
int CSocketAppView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == - 1 )
return - 1 ;
// 创建一个线程,用于接收数据。该线程执行的是方法RunSocket
DWORD nThread;
HANDLE nServerThread = CreateThread(NULL,NULL,RunSocket, this , 0 , & nThread); // 这是很重要的一个线程
CloseHandle(nServerThread);
// TODO: Add your specialized creation code here
return 0 ;
}
// 接收数据的方法
int RecvData( const SOCKET hClientSocket, char * szBuf, const int & iMaxBufSize);
DWORD WINAPI CSocketAppView::RunSocket(LPVOID lpvoid)
{
WORD wVersionRequested;
WSADATA wsaData;
char szBuf[ 1024 ];
wVersionRequested = MAKEWORD( 2 , 2 );
int iError = WSAStartup(wVersionRequested, & wsaData );
if ( iError != 0 )
.{
AfxMessageBox(TEXT( " 创建服务器端Socket初始化失败! " ));
return - 1 ;
}
if (LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 )
{
AfxMessageBox(TEXT( " 创建服务器端Socket初始化后失败! " ));
WSACleanup();
return - 1 ;
}
SOCKET hServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if ( hServerSocket == INVALID_SOCKET )
...{
AfxMessageBox(TEXT( " 创建服务器端Socket创建失败! " ));
return - 1 ;
}
// 套接字地址
struct sockaddr_in serverTcpAddr;
serverTcpAddr.sin_family = AF_INET; // 流式套接字
serverTcpAddr.sin_port = htons( 3001 ); // 端口号
serverTcpAddr.sin_addr.s_addr = inet_addr( " 127.0.0.1 " ); // IP号
// 指定本地地址
iError = bind(hServerSocket, (SOCKADDR * ) & serverTcpAddr, sizeof (serverTcpAddr));
if (iError != 0 )
{
int errorNo = WSAGetLastError();
if (errorNo == 10048 )
{
AfxMessageBox(TEXT( " 绑定失败!您的地址已经被占用! " ));
}
AfxMessageBox(TEXT( " 绑定失败! " ));
return - 1 ;
}
// 监听连接: 允许5个排队请求
iError = listen(hServerSocket, 5 );
if (iError != 0 )
{
AfxMessageBox(TEXT( " 监听失败! " ));
return - 1 ;
}
struct sockaddr_in clientTcpAddr;
SOCKET hClientSocket;
int iAddrSize = sizeof (clientTcpAddr);
while ( true )
{
hClientSocket = accept(hServerSocket, (SOCKADDR * ) & clientTcpAddr, & iAddrSize);
if (hClientSocket == INVALID_SOCKET)
{
AfxMessageBox(TEXT( " 获取数据失败! " ));
return - 1 ;
}
int iBytesReceived;
do
{
iBytesReceived = RecvData(hClientSocket, szBuf, 1024 );
if (iBytesReceived == SOCKET_ERROR)
{
int error = GetLastError();
CString e;
e.Format( " %d " , error);
e = " 遇到错误,错误代号: " + e;
AfxMessageBox(e);
break ;
}
if (iBytesReceived != 0 )
{
char szGetRec[ 16 ];
memcpy(szGetRec, szBuf, iBytesReceived);
AfxMessageBox(szGetRec);
}
/**//*
if (szBuf == "000")
{
exit(1);
} */
} while (iBytesReceived != 0 );
closesocket(hClientSocket);
}
AfxMessageBox(TEXT( " 服务器端Socket设置成功! " ));
}
int RecvData( const SOCKET hClientSocket, char * szBuf, const int & iMaxBufSize)
{
int iError;
iError = recv(hClientSocket, szBuf, iMaxBufSize, 0 );
if (iError == 0 )
{
return 0 ;
}
else if (iError == SOCKET_ERROR)
{
return SOCKET_ERROR;
}
return iError;
}
客户端接收数据的代码:
//
客户端Socket
SOCKET m_hClientSocket;
// 建立与服务器的连接
void CSocketAppView::ConnectSocket()
{
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD( 2 , 2 );
int iError = WSAStartup( wVersionRequested, & wsaData );
if ( iError != 0 )
{
AfxMessageBox(TEXT( " 初始化时出现错误 " ));
return ;
}
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 )
{
WSACleanup();
return ;
}
// 创建套接字:
// 通信发生区域:网际网区域;
// 套接字类型:流式套接字;
// 特定协议:TCP协议
m_hClientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
struct sockaddr_in serverTcpAddr;
memset( & serverTcpAddr, 0 , sizeof (serverTcpAddr));
serverTcpAddr.sin_family = AF_INET;
serverTcpAddr.sin_port = htons( 3001 );
serverTcpAddr.sin_addr.s_addr = inet_addr( " 127.0.0.1 " );
ULONG ul = 5 ;
// 设置Socket为非阻塞的
int nRetVal = ioctlsocket(m_hClientSocket, FIONBIO, & ul);
// 建立套接字连接
iError = connect(m_hClientSocket, (SOCKADDR * ) & serverTcpAddr, sizeof (serverTcpAddr));
if (iError == SOCKET_ERROR)
{
int errorNo = WSAGetLastError();
CString f;
f.Format( " %d " , errorNo);
AfxMessageBox(TEXT( " 服务器连接失败! " ));
AfxMessageBox(TEXT(f));
return ;
}
AfxMessageBox(TEXT( " 服务器连接成功! " ));
}
// 发送信息
void CSocketAppView::OnSend()
{
// TODO: Add your command handler code here
ConnectSocket();
char * chSocket = " 我是天志123132 " ;
int iBytesLeft = strlen(chSocket);
int iError;
int iIndex = 0 ;
int iBytesSent = 0 ;
while (iBytesLeft > 0 )
{
// 发送数据
iError = send(m_hClientSocket, & chSocket[iIndex], iBytesLeft, 0 );
if (iError == 0 )
{
break ;
}
else if (iError == SOCKET_ERROR)
{
// m_hClientSocket = NULL;
// ConnectSocket();
// AfxMessageBox(TEXT("发送失败!请重新发!"));
return ;
}
iBytesLeft = iBytesLeft - iError;
iIndex = iIndex + iError;
iBytesSent = iBytesSent + iError;
}
AfxMessageBox(TEXT( " 发送成功! " ));
closesocket(m_hClientSocket);
}
SOCKET m_hClientSocket;
// 建立与服务器的连接
void CSocketAppView::ConnectSocket()
{
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD( 2 , 2 );
int iError = WSAStartup( wVersionRequested, & wsaData );
if ( iError != 0 )
{
AfxMessageBox(TEXT( " 初始化时出现错误 " ));
return ;
}
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 )
{
WSACleanup();
return ;
}
// 创建套接字:
// 通信发生区域:网际网区域;
// 套接字类型:流式套接字;
// 特定协议:TCP协议
m_hClientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
struct sockaddr_in serverTcpAddr;
memset( & serverTcpAddr, 0 , sizeof (serverTcpAddr));
serverTcpAddr.sin_family = AF_INET;
serverTcpAddr.sin_port = htons( 3001 );
serverTcpAddr.sin_addr.s_addr = inet_addr( " 127.0.0.1 " );
ULONG ul = 5 ;
// 设置Socket为非阻塞的
int nRetVal = ioctlsocket(m_hClientSocket, FIONBIO, & ul);
// 建立套接字连接
iError = connect(m_hClientSocket, (SOCKADDR * ) & serverTcpAddr, sizeof (serverTcpAddr));
if (iError == SOCKET_ERROR)
{
int errorNo = WSAGetLastError();
CString f;
f.Format( " %d " , errorNo);
AfxMessageBox(TEXT( " 服务器连接失败! " ));
AfxMessageBox(TEXT(f));
return ;
}
AfxMessageBox(TEXT( " 服务器连接成功! " ));
}
// 发送信息
void CSocketAppView::OnSend()
{
// TODO: Add your command handler code here
ConnectSocket();
char * chSocket = " 我是天志123132 " ;
int iBytesLeft = strlen(chSocket);
int iError;
int iIndex = 0 ;
int iBytesSent = 0 ;
while (iBytesLeft > 0 )
{
// 发送数据
iError = send(m_hClientSocket, & chSocket[iIndex], iBytesLeft, 0 );
if (iError == 0 )
{
break ;
}
else if (iError == SOCKET_ERROR)
{
// m_hClientSocket = NULL;
// ConnectSocket();
// AfxMessageBox(TEXT("发送失败!请重新发!"));
return ;
}
iBytesLeft = iBytesLeft - iError;
iIndex = iIndex + iError;
iBytesSent = iBytesSent + iError;
}
AfxMessageBox(TEXT( " 发送成功! " ));
closesocket(m_hClientSocket);
}
在写代码时,这两段代码是在一个程序里,在类CSocketAppView中。
实例下载:代码