1. 程式人生 > >VS2015 C++ main()下進行SOCKET單執行緒網路通訊簡單例子(聊天軟體的搭建)

VS2015 C++ main()下進行SOCKET單執行緒網路通訊簡單例子(聊天軟體的搭建)

//伺服器



#include<iostream>
#include <Winsock2.h>
using namespace std;
#pragma comment(lib, "ws2_32.lib")
int main()
{
	WSADATA wsaData;
	SOCKET sockSrv;
	SOCKADDR_IN addrSrv;
	SOCKADDR_IN addrClient;//用來接受客戶端的地址資訊
	int len = sizeof(SOCKADDR);
	int err;
	WORD wVersionRequested;//用來儲存Winsock庫的版本號
	
	wVersionRequested = MAKEWORD(2, 2);//建立一個包含了請求版本號的WORD值
	err = WSAStartup(wVersionRequested, &wsaData);
	if (err != 0)
	{
		cout << "啟動使用Winsock DLL失敗" << endl;
		return 0;
	}
	if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
	{
		WSACleanup();
		cout << "啟動使用Winsock DLL失敗" << endl;
		return 0;
	}
	sockSrv = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//建立套接字
	addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	addrSrv.sin_family = AF_INET;
	addrSrv.sin_port = htons(6000);
	bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));//將套接字繫結到本地址和指定埠號上

	
	listen(sockSrv, 5);
	SOCKET sockConn = accept(sockSrv, (SOCKADDR*)&addrClient, &len);
//多執行緒從這裡開啟
//while迴圈實際是新增到這裡,程式執行到這裡會進行中斷。跳出中斷時,表示有客戶端連線。進行多
//執行緒程式設計則可以從這裡開啟執行緒(本例項為了達到單執行緒通訊(伺服器<->客服端),將訊息迴圈接收放在下
//面的迴圈裡了),例如聊天軟體,可以從這裡開啟多執行緒訊息處理後將訊息轉發到sockConn對應的客戶端,
//就形成了兩個客戶端間的通訊
//addrClient包含了連線的客戶端的IP地址

	cout << "歡迎你加入" << endl;
	send(sockConn, "歡迎你加入", 20, 0);//用返回的套接字和客戶端進行通訊。
	while (true)
	{

		char sendBuf[256];
		char recvBuf[256];
		recv(sockConn, recvBuf, strlen(recvBuf),0);
		Sleep(1000);
		if (strlen(recvBuf) > 0)
		{
			cout << recvBuf << endl;
			cout << "Input:";
			cin >> sendBuf;
			send(sockConn, sendBuf, strlen(sendBuf) + 1, 0);//用返回的套接字和客戶端進行通訊。
		}
	}
	closesocket(sockConn);
	system("pause");
	return 0;
}
//客戶端

#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include<iostream>
#include <Winsock2.h>
#include<stdlib.h>
using namespace std;

#pragma comment(lib, "ws2_32.lib")
int main()
{
	WORD wVersinRequested;
	WSADATA wsaData;
	int err;
	wVersinRequested = MAKEWORD(2, 2);
	err = WSAStartup(wVersinRequested, &wsaData);
	if (err != 0)
	{
		cout << "啟動使用Winsock DLL失敗" << endl;
		return 0;
	}
	if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
	{
		WSACleanup();
		cout << "啟動使用Winsock DLL失敗" << endl;
		return 0;
	}
	SOCKADDR_IN addrSrv;//設定伺服器端的IP和埠

	addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");//本地迴路地址
	addrSrv.sin_family = AF_INET;
	addrSrv.sin_port = htons(6000);
	SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);//將其第三個引數設為0,讓其自動選擇協議。
	connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));//與伺服器建立連線。
	Sleep(2000);
	while (1)
	{
		char recvBuf[100];
		char sendBuf[100];
		recv(sockClient, recvBuf, 100, 0);
		Sleep(1000);
		if (strlen(recvBuf) > 0)
		{
			cout << recvBuf << endl;
			cout << "Input:";
			cin >> sendBuf;
			send(sockClient, sendBuf, strlen(sendBuf) + 1, 0);
		}
		
	}
	closesocket(sockClient);

	WSACleanup();
	system("pause");

}