C++实现Socket通讯

流媒体传输协议基于TCP/IP协议实现,所谓协议就是规范,谁是最早的创建者谁就有权利制定协议,网络通讯一般需要IP地址和端口,IP用来定位计算机,端口用来定位应用,固TCP/IP协议为所有网络通讯协议的基础协议,基本上我们所接触的所有的网络通讯协议如:ftp、http、svn、rtsp...等等传输协议,只要包含IP和端口的网络通讯协议都是基于TCP/IP协议之上实现的高级传输协议。高级协议之间存在的差异性往往在于交易报文头和报文体的规范上的差异。

所以,学习流媒体我们需要先掌握C++实现套接字通讯的算法:


服务端:

// SoketServer.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#define  MAXBUFLEN 10000  
#define  PORT 6000  

typedef struct {
	unsigned short len;
	char cnt[MAXBUFLEN];
} Msg;

int _tmain(int argc, _TCHAR* argv[])
{
	//创建套接字加载套接字
	WSADATA wsaData;
	//打开套接字
	WSAStartup(MAKEWORD(1, 1), &wsaData);

	//服务端需要绑定的参数
	SOCKADDR_IN serverAddr;
	serverAddr.sin_family = AF_INET;//指定协议簇,AF_INET表示的TCP/IP协议
	serverAddr.sin_addr.s_addr = INADDR_ANY;//IP地址,INADDR_ANY|NULL默认取本机IP
	serverAddr.sin_port = htons(PORT);//绑定端口

	//创建套接字服务端
	SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

	//绑定服务端套接字和服务端IP、PORT、协议端口
	bind(serverSocket, (SOCKADDR*)&serverAddr, sizeof(SOCKADDR));
	
	//启动套接字服务监听器
	listen(serverSocket, 1);//其中第二个参数代表能够接收的最多的连接数
	printf("正在等待客户端的接入...\n");

	while(true) {
		SOCKADDR clientAddr;
		int len = sizeof(SOCKADDR);

		SOCKET clientSocket = accept(serverSocket, &clientAddr, &len);
		printf("有新客户已连接进来\n\n");
		
		char* welcome = "欢迎光临";
		Msg *wm = (Msg*)malloc(sizeof(Msg));
		wm->len = strlen(welcome);
		strcpy(wm->cnt, welcome); 

		char wmBuf[sizeof(Msg)];
		memcpy(wmBuf, wm, sizeof(Msg));
		send(clientSocket, wmBuf, strlen(wm->cnt) + sizeof(wm->len) + sizeof(char), NULL);
		free(wm);

		while(true) {
			//收消息
			Msg *m = (Msg*)malloc(sizeof(Msg));
			char receiveBuf[sizeof(Msg)];//申请消息接收缓存
			int rev_len = recv(clientSocket, receiveBuf, strlen(receiveBuf), NULL);//接收客户端发送的消息
			unsigned short len;
			memcpy(&len, receiveBuf, 2);  
			int revable_len = (int)len + sizeof(m->len) + sizeof(char);
			while(rev_len < revable_len) {
				char* bufPipe = new char[revable_len - rev_len];
				rev_len += recv(clientSocket, bufPipe, strlen(bufPipe), NULL);//如果没接收完毕,继续接收
				strcat(receiveBuf, bufPipe);
				delete bufPipe;
			}
			memcpy(m, receiveBuf, sizeof(receiveBuf));  
			printf("收到客户发来的消息长度(%d):\n%s\n", m->len, m->cnt);
			if(rev_len < 3 || !strcmp(m->cnt, "bye")) {
				printf("客户已断开连接.\n");
				break;
			}
			free(m);

			//发送消息
			Msg* _sm = (Msg*)malloc(sizeof(Msg));

			char sendBuf[sizeof(Msg)];
			printf("回复:");
			gets(_sm->cnt);
			_sm->len = strlen(_sm->cnt);
			memcpy(sendBuf, _sm, sizeof(Msg));
			send(clientSocket, sendBuf, strlen(_sm->cnt) + sizeof(_sm->len) + sizeof(char), NULL);//发送消息
			printf("共发送内容长度(%d)等待服务器回复...\n", _sm->len);
			free(_sm);
		}
		
		closesocket(clientSocket);//关闭客户端
	};
	
	closesocket(serverSocket);//关闭服务端
	WSACleanup();//释放资源操作
	system("pause");

	return 0;
}	


客户端:

// SocketClient.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#define PORT 6000 
#define DEST_IP_ADDR "192.168.1.103"
#define MAX_LEN 100000

typedef struct {
	unsigned short len;
	char cnt[MAX_LEN];
} Msg;

int _tmain(int argc, _TCHAR* argv[])
{
	//加载套接字
	WSADATA wsaData;
	WSAStartup(MAKEWORD(1, 1), &wsaData);

	SOCKADDR_IN socketAddr;
	socketAddr.sin_addr.s_addr = inet_addr(DEST_IP_ADDR);
	socketAddr.sin_family  = AF_INET;
	socketAddr.sin_port = htons(PORT);

	SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

	connect(clientSocket, (LPSOCKADDR)&socketAddr, sizeof(SOCKADDR));//注意第三个参数

	while(true) {
		//接收服务端消息
		Msg *m = (Msg*)malloc(sizeof(Msg));
		char receiveBuf[sizeof(Msg)];//申请消息接收缓存
		int rev_len = recv(clientSocket, receiveBuf, strlen(receiveBuf), NULL);//接收客户端发送的消息
		unsigned short len;
		memcpy(&len, receiveBuf, 2);  
		int revable_len = (int)len + sizeof(m->len) + sizeof(char);
		while(rev_len < revable_len) {
			char* bufPipe = new char[revable_len - rev_len];
			rev_len += recv(clientSocket, bufPipe, strlen(bufPipe), NULL);//如果没接收完毕,继续接收
			strcat(receiveBuf, bufPipe);
			delete bufPipe;
		}
		memcpy(m, receiveBuf, sizeof(receiveBuf));  
		printf("收到服务器发来的消息长度(%d):\n%s\n", m->len, m->cnt);


		//发送消息
		Msg* _m = (Msg*)malloc(sizeof(Msg));

		char sendBuf[sizeof(Msg)];
		printf("回复服务器:");
		gets(_m->cnt);
		_m->len = strlen(_m->cnt);
		memcpy(sendBuf, _m, sizeof(Msg));
		
		send(clientSocket, sendBuf, strlen(_m->cnt) + sizeof(_m->len) + sizeof(char), NULL);
		printf("共发送内容长度(%d)等待服务器回复...\n", _m->len);
		free(_m);
	}

	closesocket(clientSocket);
	WSACleanup();
	system("pause");
	return 0;
}


  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值