1. 程式人生 > >VS2013中C++方式的程序間通訊---socket

VS2013中C++方式的程序間通訊---socket

伺服器程序:

#include <Windows.h>

#include <iostream>
using namespace std;

#pragma comment(lib, "ws2_32.lib")

SOCKET ServerSocket;
SOCKET CientSocket;

#define  IP_ADDRESS "127.0.0.1"

#define BUF_MAX_LEN      500*1024   

int main(int argc, char *argv[])
{
	WSADATA  Ws;
	struct sockaddr_in LocalAddr, ClientAddr;
	int Ret = 0;
	int AddrLen = 0;
	HANDLE hThread = NULL;

	//初始化Windows socket網路庫
	if (WSAStartup(MAKEWORD(2, 2), &Ws) != 0)  //初始化win socket網路庫,申請2.2的版本,並判斷是否初始化成功  
	{
		cout << "Init windows socket failed::" << GetLastError() << endl;
		return 1;
	}

	//建立socket    
	ServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (ServerSocket == INVALID_SOCKET)
	{
		cout << "Create socket failed::" << GetLastError() << endl;
		return 1;
	}

	LocalAddr.sin_family = AF_INET;  //sin_family指代協議族,在socket程式設計中只能是AF_INET  
	LocalAddr.sin_addr.s_addr = inet_addr(IP_ADDRESS);  //sin_addr儲存IP地址,使用in_addr這個資料結構  
	LocalAddr.sin_port = htons(0); //sin_port儲存埠號(使用網路位元組順序)   
	memset(LocalAddr.sin_zero, 0x00, 8);

	//繫結socket
	Ret = ::bind(ServerSocket, (struct sockaddr*)&LocalAddr, sizeof(LocalAddr));
	if (Ret != 0)
	{
		cout << "Bind socket failed::" << GetLastError() << endl;
		return 1;
	}

	int iLen = sizeof(LocalAddr);
	getsockname(ServerSocket, (struct sockaddr *)&LocalAddr, &iLen);//得到本地的IP地址和埠號
	int port = LocalAddr.sin_port;

	//監聽該socket
	Ret = listen(ServerSocket, 10);
	if (Ret != 0)
	{
		cout << "Listen socket failed::" << GetLastError() << endl;
		return 1;
	}

	while (true)
	{
		AddrLen = sizeof(ClientAddr);
		//等待客戶端的連線請求
		CientSocket = accept(ServerSocket, (struct sockaddr*)&ClientAddr, &AddrLen);
		if (CientSocket == INVALID_SOCKET)
		{
			cout << "Accept Failed::" << GetLastError() << endl;
			break;
		}

		while (true)
		{
			int Ret = 0;
			char recv_buff[BUF_MAX_LEN] = { 0 };

			//從socket中讀取資料
			Ret = recv(CientSocket, recv_buff, BUF_MAX_LEN, 0);

			if (Ret == 0 || Ret == SOCKET_ERROR)
			{
				//連線斷開,客戶端掉線
				break;
			}

			//處理資料
		}

		closesocket(ServerSocket);
		closesocket(CientSocket);
		WSACleanup();
	}

	return 0;
}

客戶端程序:

#include <Windows.h>

#include <iostream>
using namespace std;

#pragma comment(lib, "ws2_32.lib")

SOCKET CientSocket;

#define  IP_ADDRESS "127.0.0.1"
#define BUF_SIZE 8
#define BUF_MAX_LEN      500*1024   

int main(int argc, char *argv[])
{
	WSADATA  Ws;
	struct sockaddr_in ServerAddr;
	int Ret = 0;
	int AddrLen = 0;
	HANDLE hThread = NULL;

	//初始化Windows Socket庫    
	if (WSAStartup(MAKEWORD(2, 2), &Ws) != 0)
	{
		cout << "Init windows socket failed::" << GetLastError() << endl;
		return 1;
	}

	//建立socket    
	CientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (CientSocket == INVALID_SOCKET)
	{
		WSACleanup();
		cout << "Create Socket Failed::" << GetLastError() << endl;
		return 1;
	}

	ServerAddr.sin_family = AF_INET;
	ServerAddr.sin_addr.s_addr = inet_addr(IP_ADDRESS);
	int port = 0; //此處要為伺服器繫結的埠號
	ServerAddr.sin_port = port;
	memset(ServerAddr.sin_zero, 0x00, BUF_SIZE);

	Ret = ::connect(CientSocket, (struct sockaddr*)&ServerAddr, sizeof(ServerAddr));
	if (Ret == SOCKET_ERROR)
	{
		cout << "Connect Error::" << GetLastError() << endl;
		closesocket(CientSocket);
		WSACleanup();
		return 1;
	}

	while (true)
	{
		int Ret = 0;

		char recv_buff[BUF_MAX_LEN] = { 0 };

		Ret = recv(CientSocket, recv_buff, BUF_MAX_LEN, 0);
		if (Ret == 0 || Ret == SOCKET_ERROR)
		{
			cout << "Client disconect::" << GetLastError() << endl; 
			break;
		}
		
		//處理接收到的資料
	}

	return 0;
}

傳送資料的程式碼:

	int Ret = 0;
	char data[] = { 100 };
	//CientSocket為客戶端的socket,不管是伺服器像客戶端發訊息還是客戶端向伺服器發訊息
	Ret = send(CientSocket, (char *)data, sizeof(data), 0);   
	if (Ret == SOCKET_ERROR)
	{
		cout << "Send msg failed::" << GetLastError() << endl;
		return;
	}