socket传输速率过低

gabriel_wangjx 2011-10-24 05:25:02
用socket传输数据

发送端为客户端C++编写 接收端为服务器端java编写

实测传输速率在0.36M/s 用飞鸽传输传送文件速度大于7M/s 可以排除网络问题

请各位大侠指点一二 看看是什么原因导致传输速率过慢

发送端代码


void __cdecl SendData(LPVOID param)
{

restart:
skVersion = MAKEWORD(2,2);
//套接字初始化
WSAStartup(skVersion,&wsaData);

hostEntry = gethostbyname(CenterIp);


//中心节点网络信息
RecverInfo.sin_family = PF_INET ;//设定网络协议
RecverInfo.sin_addr = *((LPIN_ADDR)*hostEntry->h_addr_list);/*inet_addr(CenterIp.GetBuffer());*/
RecverInfo.sin_port = htons(7745) ;//中心节点端口7745为接受数据端口

DataSender = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
loop:
//与接受端建立连接 DataSender需要进行连接的套接字 serverInfo网络地址
int rVal=connect( DataSender ,(LPSOCKADDR)&RecverInfo , sizeof(RecverInfo) );
//如果连接失败
if(rVal==SOCKET_ERROR)
{
//::MessageBox(NULL,_T("连接失败"),_T("Error"),MB_OK);
goto loop;
IsSend = FALSE;
}
int counter = 0;
clock_t start,finish;

//测试每两个定时器周期之间的时间
LARGE_INTEGER t1,t2,t3;
LONGLONG qt1,qt2,qt3,qt4;
LARGE_INTEGER litmp;
double freque,realtime;

QueryPerformanceFrequency(&litmp);//获得时钟频率
freque=(double)litmp.QuadPart;
//
QueryPerformanceCounter(&t1);//获得初始值
qt1 = t1.QuadPart;

while (counter<10000)//主线程结束后自动消亡
{
counter++;


//准备发送数据
unsigned long DataPackLen = 0 ;//数据包大小
unsigned long LeftDataLen = 0 ;//剩余的字节数
unsigned long SendDataLen = 0 ;//发送的字节数

//ConstructDataPack返回的是指向24个char类型的指针
SendUnit = ConstructDataPack(/*LoggerDataPtr ,rtirefname ,rtiinstname ,rtitime*/);//发送的数据

unsigned int SendOffset = 0 ;//偏移量

DataPackLen = 72;
//myDataSize = 0 ;
LeftDataLen = DataPackLen ;
unsigned int SendSoFar = 0 ;
//开始发送
do
{
do
{
if ( LeftDataLen > SEND_BUFFER_SIZE)
{
SendDataLen = SEND_BUFFER_SIZE ;
}
else
SendDataLen = LeftDataLen ;



SendSoFar = send( DataSender ,/*&attemp*/SendUnit+SendOffset ,SendDataLen ,0 ) ;//发送
//cout<<"send "<<SendSoFar<<"bytes\n";
if ( SendSoFar == SOCKET_ERROR )
{
int iErr = ::GetLastError();
TRACE("SendFileToRemoteRecipient returned a socket error\
while sending chunked file data\n\
\tNumber of Bytes sent = %d\n\
\tGetLastError = %d\n", SendSoFar, iErr );

//::MessageBox(NULL ,_T("Socket Error")+iErr , _T("Error") , MB_OK ) ;

//IsSend = FALSE ;
shutdown( DataSender , SD_SEND );//通知不再发送数据
closesocket( DataSender ) ;//关闭套接字
goto restart;

}

SendOffset += SendSoFar ;//设定偏移量

SendDataLen -= SendSoFar ;//已发送的字节数

LeftDataLen -= SendSoFar ;//剩余的字节数


} while (SendDataLen > 0);


} while (LeftDataLen > 0);


//delete [] tmpptr;
delete [] SendUnit;
SendUnit = NULL;
}

QueryPerformanceCounter(&t2);//获得初始值
qt2 = t2.QuadPart;

double currT=(double)(qt2-qt1);
double currRealT =currT/freque;//获得对应的时间值
printf("发送100000次数据包,花费时间%f\n",currRealT);


SetEvent(Event);

//return false;
}

接收端代码

import java.net.*;
import java.nio.ByteBuffer;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Vector;
import java.io.*;
public class DataRecver extends Thread {
public Vector<byte[]> bytevector=new Vector<byte[]>();
public byte[] bytes1=new byte[1024];
public int a=0;
// 本地服务器套接字
public ServerSocket MyDataRecvSvr ;
//端口号 选定端口7745
public int portNum ;
//接收端套接字
public Socket MyDataRecvSock ;
//数据输入流
public DataInputStream MyDataStream;
//constructor
public DataRecver(){
MyDataRecvSvr = null ;
portNum = 7745 ;
MyDataRecvSock = null ;
MyDataStream = null ;
start() ;//启动线程
}
//线程入口
public void run(){

try{

MyDataRecvSvr = new ServerSocket(portNum) ;//建立服务器套接字
MyDataRecvSock = MyDataRecvSvr.accept() ;//阻塞监听
InputStream is = MyDataRecvSock.getInputStream() ;//输入流

MyDataStream = new DataInputStream(is) ;//数据流

//获取数据信息
//Vector<Byte>bytes=new Vector<Byte>();
long start;
long end;
long s;
long e;
long all=0;

byte[]bytes=new byte[1024];

while(true/*IsOperating*/)
{


while(MyDataStream.available()>0)
{
int tmpsize=MyDataStream.available();
byte []tmpbytes=new byte[tmpsize];
//MyDataStream.readFully(MyBytes.bytes, 0, 10);
MyDataStream.readFully(tmpbytes, 0, tmpsize);
//MyBytes.bytes.addAll(bytes)
for(int i=0;i<tmpsize;i++)
{
MyBytes.bytes.add(tmpbytes[i]);
}


}


try {
Thread.sleep(50);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}

}
}

catch(IOException e){
e.printStackTrace();



}

}

public static void main(String[] args)
{
new DataRecver();


}

}


...全文
533 13 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
zilaishuichina 2013-04-07
  • 打赏
  • 举报
回复
lz应该 1、测试一下 ConstructDataPack的效率,lz的循环里面并不是仅仅只有send的 2、加大SendDataLen的大小,lz代码里面默认最大是只有72个字节,而考虑到windows系统接收/发送时,默认会锁定一个页面大小的内存(4K),再考虑到实际网络环境下,数据包在路由上的一次通过率(1K),lz可以设置send一次发送1K的数据 3、java接收端readFully解包的速度,如果readFully解包效率比较低(发送速率远大于你解包的速率),数据都阻塞在网卡的缓存上,你send的速率就会受到影响
赵4老师 2013-04-07
  • 打赏
  • 举报
回复
ping有多快?
码记 2013-04-06
  • 打赏
  • 举报
回复
我用的是select。
ris1208 2012-08-24
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]
我以前用c写过。影响性能的是:
1.send()和read()时的buf大小
2.不要在sen0d()和read()循环时候处理其他事情,这样效果就快了
[/Quote]

请问从send()到read()的速率会有多快呢?
gabriel_wangjx 2011-10-26
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 qq120848369 的回复:]

关闭Nagle选项是很重要的。
[/Quote]
如果关闭Nagle算法 速度更慢
gabriel_wangjx 2011-10-26
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 qq120848369 的回复:]

关闭Nagle选项是很重要的。
[/Quote]
如果关闭了 速度会更慢
gabriel_wangjx 2011-10-26
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 cppxiaojiang 的回复:]

用多线程,速度肯定会有很大提升。
[/Quote]
你的意思是多线程并行发送?
qq120848369 2011-10-24
  • 打赏
  • 举报
回复
关闭Nagle选项是很重要的。
墨菲斯 2011-10-24
  • 打赏
  • 举报
回复
用多线程,速度肯定会有很大提升。
jh19870906 2011-10-24
  • 打赏
  • 举报
回复
我以前用c写过。影响性能的是:
1.send()和read()时的buf大小
2.不要在sen0d()和read()循环时候处理其他事情,这样效果就快了
qq120848369 2011-10-24
  • 打赏
  • 举报
回复
TCP么.
恨天低 2011-10-24
  • 打赏
  • 举报
回复
肯定是程序写得有问题。WinSock这套驱动做得不错的。比WinPcap性能好很多。

缺点就是不开源而已。
我要戒烟了 2011-10-24
  • 打赏
  • 举报
回复
没有实际此时过,帮你顶

65,194

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧