服务器的编写也是自己第一次做的事情,这次是因为项目需要,服务器(专门负责存储数据,音频和视频数据)。这里主要说一下,服务器的编写,需要将UDP和TCP两种连接方式放在一个服务器程序上。
一开始自己没有头绪,觉得如何让服务器既接收UDP包,又接收TCP包。因为两者是不同的传输方式。其实这个很好解决,让服务器多开几个线程,每个线程服务则一项就可以了。
我在程序里是这么做的,UDP两个线程,一个专门专门负责收音频,一个专门负责收视频。
static DWORD WINAPI server::VIDEOThread(LPVOID UDPPORT)
{
//运行参数
unsigned short int PORT=(unsigned short int)UDPPORT;
//接收socket
SOCKET m_socket;
//相关地址
struct sockaddr_in local;
struct sockaddr_in from;
int fromlen =sizeof(from);
local.sin_family=AF_INET;
local.sin_port=htons(PORT); ///监听端口
local.sin_addr.s_addr=INADDR_ANY; ///本机
m_socket=socket(AF_INET,SOCK_DGRAM,0);
int result=0;
//绑定
result = bind(m_socket,(struct sockaddr*)&local,sizeof(local));
if(result != 0){
printf("video bind error,%d\n",WSAGetLastError());
return 0;
}
char BUFFER[MAX_PACKBUFFER_SIZE];
//设置成阻塞模式
int iMode = 0;
result = 0;
result = ioctlsocket(m_socket,FIONBIO,(u_long FAR*) &iMode);
if(result == SOCKET_ERROR ){
printf("video set error,%d\n",WSAGetLastError());
return 0;
}
while(1){
if (recvfrom(m_socket,BUFFER,sizeof(BUFFER),0,(struct sockaddr*)&from,&fromlen)!=SOCKET_ERROR){
}
}
return 0;
}
接受音频的操作和这个差不多,将UDP接受端口传入当做参数。
服务器需要一个TCP连接作为客户端和另外 一个服务器进行连接,所以需要两外一个线程负责和这一个服务器进行连接,这里我采用的一般的方法。直接进行阻塞的方式和该服务器进行通信,在上面的接收数据的socket的中,我也是设置为阻塞模式了,在C++中,本来默认应该是阻塞模式,不过貌似也不是,最好还是显示的设置一下阻塞模式。然后这样不至于让这个线程疯狂的跑起来。
static DWORD WINAPI server::ClientThread(LPVOID UDPPORT)
{
if(connect(m_socket, (struct sockaddr *)&server, sizeof(SOCKADDR_IN) ) != SOCKET_ERROR){
while(true){
ret = recv(m_socket, szMessage, MAX_PACKBUFFER_SIZE, 0);
if(ret>0){
}
else if(ret == -1){
printf("与服务器失去连接,请重连\n");
return 0;
}
}
}
return 0;
}
另外自己作为 一个服务器接受其他客户端的连接,是用IOCP模式进行的。代码一搜一大堆,我只是将其进行了稍微的改造用在我的程序中,其中的原理,只是理解一些,不过理解的不多,有些该注意的是要注意的,这个我会专门一篇文章写。
欢迎一起探讨。