【GamingAnywhere源码分析之知识补充三】GA并发连接改造

本文详细介绍了GamingAnywhere(GA)的并发连接改造,包括服务端监听客户端请求、保存客户端连接并启动对应游戏、独立断开连接等功能。改造后的GA支持客户端并发连接,每个客户端可以看到各自的游戏画面,且断开连接不会影响其他客户端。实现中利用了Live555的RTSP通信,通过RTSP的Option阶段传递游戏参数,并通过钩子技术实现游戏画面的捕捉。未来工作计划包括加入用户认证机制和用户存储挂载。
摘要由CSDN通过智能技术生成

        GA原有的实现中对并发连接并不支持,表现出的是先启动服务端,服务端通过指定的游戏配置文件来启动特定的游戏,然后等待客户端进行连接,当客户端连接进来时将捕捉到的游戏画面通过H.264压缩后,通过RTP、RTSP等协议将其发送到客户端。当服务端启动一个游戏有多个客户端连接进来时,多个客户端看到的画面是一样的,因为它们都通过相同的端口来接收数据。这种情况并不满足实际使用的需要,为了真正实现并发改造,需要实现一下功能:

1> GA服务端启动后应该一直监听,每当有客户端的请求到来时就建立一个新的链接,根据客户端传递的游戏参数启动对应的游戏。

2> GA accept客户端的连接请求后应该能将该socket保存下来,并在通信时使用,使每个连接过来的客户端能够看到属于自己的画面。

3> 既然能并发连接,那么每个连接过来的客户端就能够单独断开连接而不妨碍其它现有的连接着的客户端。

第一部分的实现:

        第一部分的实现需要解决的问题有:1》服务端要能够一直监听客户端的请求。2》服务器端要能够解析客户端传来的参数,从而解析出该客户端需要启动哪个游戏。

        服务器端一直监听的实现想必大家都有思路,就是利用socket一直listen就可以了,等到accept之后,启动receiveclient线程,由该线程负责解析参数,以及后期的其它操作,至于socket的使用就不在里详细讲解了,但需要注意的一点就是:Linux和Windows下socket的使用有一些差异,Windows下Socket使用前必须使用WSAStartup()完成对Winsock环境的初始化,相关实现代码如下(注意标红部分的使用):

#ifdef WIN32
	WSADATA wd;
	if(WSAStartup(MAKEWORD(2,2), &wd) != 0)
		return -1;
#endif

	if((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
		fprintf(stderr, "socket creating failed: %s\n", strerror(errno));
		return -1;
	}

	//
	do {
#ifdef WIN32
		BOOL val = 1;
		setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char*) &val, sizeof(val));
#else
		int val = 1;
		setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
#endif
	} while(0);
	//
	bzero(&sin, sizeof(sin));
	sin.sin_family = AF_INET;
	sin.sin_port = htons(8554);

	//
	if(bind(s, (struct sockaddr*) &sin, sizeof(sin)) < 0) {
		fprintf(stderr, "socket binding failed: %s\n", strerror(errno));
		return -1;
	}
	if(listen(s, 256) < 0) {
		fprintf(stderr, "socket listening failed: %s\n", strerror(errno));
		return -1;
	}
	//
	do {
		int csinlen;
		pthread_t thread;
		SOCKET cs;
		struct sockaddr_in csin;
		//
		csinlen = sizeof(csin);
		bzero(&csin, sizeof(csin));
		if((cs = accept(s, (struct sockaddr*) &csin, &csinlen)) < 0) {
			fprintf(stderr, "socket acceptting error: %s\n", strerror(errno));
			return -1;
		}

		fprintf(stderr, "client connected from %s:%d\n",
		inet_ntoa(csin.sin_addr), htons(csin.sin_port));
		
		// tunning sending window
		do {
			int sndwnd = 8388608;	// 8MB
			if(setsockopt(cs, SOL_SOCKET, SO_SNDBUF, (const char *)&sndwnd, sizeof(sndwnd)) == 0) {
				fprintf(stderr, "*** set TCP sendi
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值