接受端是在VS2010下开发的控制台程序,接受采取的是多线程去接收,VS2010不自带pthread库,这个库是Linux下线程操作库,习惯了在Linux下开发,就把这个库文件安装到VS的安装目录。
线程库下载地址:pthreads-w32-2-8-0-release.zip
控制台程序exe文件(采用的是静态编译,只有一个exe文件,方便操作),下载地址:udpserver.exe
exe界面效果如下:
控制台exe 包解压后有两个文件 分别是run_server.bat和udpserver.exe ,因为udpserver.exe是控制台程序,你直接打开会闪退,也可在控制台cmd命令里面去执行这个控制台程序,这样避免闪退,但是比较麻烦,这里提供一个run_server.bat脚本程序,直接运行这个udpserver.exe控制台程序,run_server.bat文本如下:
rem *.exe
udpserver.exe 8888 61440 1 3
pause /* 启动完后暂停 方便看控制台打印程序 */
安装线程库:解压pthreads-w32-2-8-0-release.zip 后,执行exe文件,在Browse里面选择安装目录,然后点击Extract,Done。 安装完成后把安装目录下的Pre-built.2目录下面的include lib分别拷贝到VS安装目录,VC目录下面的 include lib 。同时需要把pthreadVC2.dll拷贝到操作系统目录,及C:\WINDOWS\system32下面 不然运行exe会提示找不到pthreadVC2.dll这个库文件。
udp_server.cpp
#include "stdafx.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define Maxlen 65535
char buffer[Maxlen];
#pragma comment(lib,"ws2_32.lib")
#pragma comment(lib,"pthreadVC2.lib")
static int count;
struct Socket_Pagram
{
int SockFd;
int Thread_Num;
int One_Frame_Size;
int Recevie_Frame_Num;
int Client_Thread_Nums;
int Server_Thread_Nums;
double TimeTotal;
pthread_t Pthread_Id;
};
struct Socket_Pagram *Pagram;
pthread_mutex_t work_mutex;
void SocketInit()
{
WSADATA wsaData;
WORD version=MAKEWORD(2,0);
int ret=WSAStartup(version,&wsaData);
if(ret!=0)
printf("初始化失败");
}
void CloseSocket()
{
if(WSACleanup()!=0)
printf("clean失败");
}
void * RecevieData(void *arg)
{
struct Socket_Pagram *ptr = (struct Socket_Pagram *)arg;
char *buff = "send is complete";
char buffer[65535] ;
struct sockaddr_in cliaddr;
LPSOCKADDR Client_Addr = (LPSOCKADDR)&cliaddr;
int len = sizeof(cliaddr);
unsigned long AllByteSize = (ptr->Client_Thread_Nums*ptr->One_Frame_Size);
int i,ret;
long long count=0;
ret = pthread_mutex_init(&work_mutex,NULL);
while(1)
{
if((count=recvfrom(ptr->SockFd,buffer,sizeof(buffer),0,Client_Addr,&len))>=20)
{
ptr->Recevie_Frame_Num++;
printf("thread %d accept Frame size :%d\n",ptr->Thread_Num,ptr->Recevie_Frame_Num);
}
else
{
printf("thread %d accept is complete!\n",ptr->Thread_Num);
break;
}
}
return NULL;
}
void print_usage(char *file)
{
printf("Usage:\n");
printf("%s \n", file);
}
int main(int argc,char *argv[])
{
int sockfd,i,ret;
struct sockaddr_in servaddr;
float lost_pack = 0;
int Port,SIZE,Clien_Thread_Num,Self_Thread_Nums;
int All_Frame = 0;
if (argc != 5)
{
print_usage(argv[0]);
return -1;
}
Port = strtoul(argv[1], NULL, 0);
SIZE = strtoul(argv[2], NULL, 0);
Clien_Thread_Num = strtoul(argv[3], NULL, 0);
Self_Thread_Nums = strtoul(argv[4], NULL, 0);
Pagram = (struct Socket_Pagram *)malloc(Self_Thread_Nums*sizeof(struct Socket_Pagram));
SocketInit();
if((sockfd=socket(AF_INET,SOCK_DGRAM,0))<0)
{
printf("socket failed");
CloseSocket();
return 0;
}
memset(&servaddr,0,sizeof(servaddr));
servaddr.sin_family=AF_INET;
servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
servaddr.sin_port=htons(Port);
if(bind(sockfd,(LPSOCKADDR)&servaddr,sizeof(servaddr))!=0)
{
printf("bind error");
CloseSocket();
return 0;
}
int flag = (32*1024*1024);
setsockopt(sockfd,SOL_SOCKET,SO_RCVBUF,(char *)&flag,sizeof(flag));
for(i=0;i
By Design :Linux_Google