コンピュータネットワークシステム学習エッセンス総括(三):伝送層--4(ソケットプログラミング実戦、全二重通信)
8461 ワード
フルデュプレクス通信.本文は前文の単双共通信モードの下で(接続:コンピュータネットワークシステム学習精華総括(三):伝送層--3(ソケットプログラミング実戦、半二重通信))、簡単なマルチスレッドプログラミングを採用して実現し、コードはほとんどの文に注釈を含む.
サービス側コード:
クライアントコード:
サービス側コード:
#include
#include
#include //WSAADATA
#include
#pragma comment (lib, "ws2_32.lib")
#pragma warning(disable : 4996)
/* , */
//--------------- -----------------------
const int bufLen = 1024;
char reciveBuf[bufLen]; // ,
char sendBuf[bufLen]; //
//--------------- -----------------------
using namespace std;
WSAEVENT bExit = WSACreateEvent();//
//
DWORD WINAPI recvMessage(LPVOID parsock)
{
SOCKET recvsock = (SOCKET) parsock; //
int err; //
while (true)
{
memset(reciveBuf,0,sizeof(reciveBuf));//
if (recv(recvsock, reciveBuf, bufLen, 0) != SOCKET_ERROR)
{//
cout << " :" << reciveBuf << endl;
if (strcmp(reciveBuf, "bye") == 0)
{// , bye
SetEvent(bExit);// , ,
break;
}
}
else
{//
err = WSAGetLastError();
if (err == WSAECONNRESET)
{//
cout << "The peer is closed" << endl;
continue;//
}
SetEvent(bExit);//f
break;
}
}
closesocket(recvsock);//
WSACleanup();//
return 0;
}
//
DWORD WINAPI sendMessage(LPVOID parsock)
{
SOCKET sendsock = (SOCKET)parsock; //
while (true)
{
cout << " :" << endl;
cin.getline(sendBuf, sizeof(sendBuf));
send(sendsock, sendBuf, sizeof(sendBuf),0);//
if (strcmp(sendBuf, "bye") == 0)
{
SetEvent(bExit);//
break;
}
}
closesocket(sendsock);
WSACleanup();//
return 0;
}
int main()
{
// , socket2.0 ,
WSADATA wsaDATA;
//WSAStartup(MAKEWORD(2, 0), &wsaDATA);
if (WSAStartup(MAKEWORD(2, 0), &wsaDATA) != 0)
{//
std::cout << " " << std::endl;
return -1;
}
// ,int socket(int domain,int type,int protocol)
/*socket —— ( 、 ): 。AF_INET TCP/IPv4,AF_INET6 TCP/IPv6,AF_LOCAL AF_UNIX , ,
socket —— :socket ,SOCK_STREAM: TCP, , , , , , 。
SOCK_DGRAM: UDP, , , , ,
SOCK_RAW: IP, , , , 。
socket —— : , 0 ,IPPROTO_TCP\IPPTOTO_UDP\IPPROTO_SCTP\IPPROTO_TIPC,
type protocol
*/
SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, 0);// , ipv4,TCP
if (serverSocket == INVALID_SOCKET)
{
std::cout << "socket " << std::endl;
WSACleanup();//
return -1;
}
//
struct sockaddr_in sockAddr;// socket ,struct sockaddr_in/sockaddr_in/SOCKADDR_IN
sockAddr.sin_family = AF_INET;// ( )
sockAddr.sin_port = htons(8888);// ,
sockAddr.sin_addr.s_addr = inet_addr("192.168.0.103");//inet_addr IP ,127.0.0.1
// s_addr S_un.S_addr
//sockAddr.sin_addr.S_un.S_addr= inet_addr("127.0.0.1");
int ret = bind(serverSocket, (struct sockaddr*)&sockAddr, sizeof(SOCKADDR_IN));//LPSOCKADDR struct sockaddr*、SOCKADDR*
//int bind(int sockfd,const struct socketaddr * addr,
if (ret == SOCKET_ERROR)//
{
std::cout << " !" << std::endl;
WSACleanup();//
closesocket(serverSocket);//
return -1;
}
//
listen(serverSocket, 5);//5
if (listen(serverSocket, 5) < 0)//listen 0 , -1
{
std::cout << " !" << std::endl;
WSACleanup();//
closesocket(serverSocket);//
return -1;
}
//
//SOCKADDR clsocket;
SOCKADDR clsocket;
int len = sizeof(SOCKADDR);
SOCKET newSock = accept(serverSocket, (SOCKADDR*)&clsocket, &len);
if (newSock == SOCKET_ERROR)
{
std::cout << " —— !" << std::endl;
return -1;
}
std::cout << " —— " << std::endl;
// ,
HANDLE send_thread, recv_thread;// ,
DWORD nSthread, nRthread; // ID
/* CreateThread()
,0 1MB
,
, ,0 ,CREAT——SUSPENDED , ResumeThread()
*/
send_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)sendMessage, (LPVOID)newSock, 0, &nSthread);//
recv_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)recvMessage, (LPVOID)newSock, 0, &nRthread);//
/* , bExit ( SetEvent() )
*/
WaitForSingleObject(bExit, INFINITE);
closesocket(newSock);
closesocket(serverSocket);
WSACleanup();
return 0;
}
クライアントコード:
#include
#include
#include
#pragma comment (lib, "ws2_32.lib")
#pragma warning(disable : 4996)
using namespace std;
/* */
//--------------- -----------------------
const int bufLen = 1024;
char reciveBuf[bufLen];//
char sendBuf[bufLen];//
//--------------- -----------------------
WSAEVENT bExit = WSACreateEvent();//
//
DWORD WINAPI recvMessage(LPVOID parsock)
{
SOCKET recvsock = (SOCKET)parsock; //
int err; //
while (true)
{
memset(reciveBuf, 0, sizeof(reciveBuf));//
if (recv(recvsock, reciveBuf, bufLen, 0) != SOCKET_ERROR)
{//
cout << " :" << reciveBuf << endl;
if (strcmp(reciveBuf, "bye") == 0)
{// , bye
SetEvent(bExit);// , ,
break;
}
}
else
{//
err = WSAGetLastError();
if (err == WSAECONNRESET)
{//
cout << "The peer is closed" << endl;
continue;//
}
SetEvent(bExit);//f
break;
}
}
closesocket(recvsock);//
WSACleanup();//
return 0;
}
//
DWORD WINAPI sendMessage(LPVOID parsock)
{
SOCKET sendsock = (SOCKET)parsock; //
while (true)
{
cout << " :" << endl;
cin.getline(sendBuf, sizeof(sendBuf));
send(sendsock, sendBuf, sizeof(sendBuf), 0);//
if (strcmp(sendBuf, "bye") == 0)
{
SetEvent(bExit);//
break;
}
}
closesocket(sendsock);
WSACleanup();//
return 0;
}
int main()
{
//
WSADATA data;
//WSAStartup(MAKEWORD(2, 0), &data);
if (WSAStartup(MAKEWORD(2, 0), &data) != 0)// 0
{
std::cout << " !" << std::endl;
return -1;
}
SOCKET client = socket(AF_INET, SOCK_STREAM, 0);//
if (client == INVALID_SOCKET)
{
std::cout << " !" << std::endl;
WSACleanup();//
return -1;
}
// ,ip , ,
sockaddr_in addr;
addr.sin_addr.S_un.S_addr = inet_addr("192.168.0.103");
addr.sin_family = AF_INET;
addr.sin_port = htons(8888);
std::cout << " ......" << std::endl;
int ret = connect(client, (SOCKADDR*)&addr, sizeof(addr));
if (ret == -1)// 0 ,-1
{
std::cout << " !" << std::endl;
return -1;
}
std::cout << " !" << std::endl;
// ,
HANDLE send_thread, recv_thread;// ,
DWORD nSthread, nRthread; // ID
/* CreateThread()
,0 1MB
,
, ,0 ,CREAT——SUSPENDED , ResumeThread()
*/
send_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)sendMessage, (LPVOID)client, 0, &nSthread);//
recv_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)recvMessage, (LPVOID)client, 0, &nRthread);//
/* , bExit ( SetEvent() )
*/
WaitForSingleObject(bExit, INFINITE);
closesocket(client);
WSACleanup();
return 0;
}