winsock(udp)收到大量数据之后

doudoushen 2004-05-01 11:26:24
我那个程序winsock(udp)收到大量数据之后 机器越来越慢 最后程序就死了
我估计是收到数据后处理不能跟上发过来数据的速度 导致udp的缓存爆掉
大家帮我想想办法
1 比如及时清空缓存
2 故意丢掉点数据包(因为可能许多数据包内的数据是一样的) 谢谢
...全文
257 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
goodname008 2004-07-20
  • 打赏
  • 举报
回复
// 这是我5月份时用C写的一个小程序,翻译成VB的源代码肯定不是问题。


/********************************************************************/
/* 字节流发送器 作者: 卢培培 (2004.5) */
/* */
/* 功能: 向指定的计算机发送字节流 */
/* */
/* 用法: */
/* Send <IP:port> <bytes stream> */
/* <bytes stream> */
/* _computername Local computer name */
/* _mac Local network adapter MAC address */
/* */
/* 例子: */
/* Send 127.0.0.1:1510 hello, world. */
/* Send 127.0.0.1:1510 MAC: _mac ComputerName: _computername */
/********************************************************************/

// 包含头文件
#include "stdafx.h"

// 定义发送字节流的缓冲区大小
#define BUFSIZE 1024

// 函数声明
bool GetMacAddress(char *);

// 主程序入口函数
int main(int argc, char* argv[])
{
// 初始化帮助信息
char help[BUFSIZE];
strcpy(help, "Send bytes stream to a specific computer, written by LPP. (2004.5)\n");
strcat(help, "usage:\n ");
strcat(help, argv[0]);
strcat(help, " <IP:port> <bytes stream>\n\n");
strcat(help, " <bytes stream>\n");
strcat(help, " _computername Local computer name\n");
strcat(help, " _mac Local network adapter MAC address\n\n");
strcat(help, "example:\n ");
strcat(help, argv[0]);
strcat(help, " 127.0.0.1:1510 hello, world.\n ");
strcat(help, argv[0]);
strcat(help, " 127.0.0.1:1510 MAC: _mac ComputerName: _computername\n");


// 检查参数个数是否符合要求, 不得少于2个参数
if (argc < 3)
{
cout<<help<<endl;
return 1;
}

// 检查第1个参数是否符合要求, 正确格式为: IP地址:端口号, 例:192.168.0.1:1015
if (strstr(argv[1], ":") - argv[1] <= 0)
{
cout<<help<<endl;
return 1;
}

// 从第1个参数中提取IP地址和端口号
char remoteIP[16];
int remotePort;
memset(remoteIP, 0, 16);
memcpy(remoteIP, argv[1], strstr(argv[1], ":") - argv[1]);
argv[1] = argv[1] + (strstr(argv[1], ":") - argv[1]) + 1;
remotePort = atoi(argv[1]);
if (inet_addr(remoteIP) == -1)
{
cout<<"非法的IP地址."<<endl;
return 1;
}
if (htons(remotePort) == 0)
{
cout<<"非法的端口号."<<endl;
return 1;
}

// 获得要发送的内容
char *Message = (char *)malloc(BUFSIZE);
memset(Message, 0, BUFSIZE);
for (int i = 2; i < argc; i++)
{
strcat(Message, argv[i]);
if (i != argc - 1)
strcat(Message, " ");
}

// 处理自定义环境变量: _computername 为计算机名, _mac 为本机网络适配器MAC地址
char *lwrMessage = strlwr(strdup(Message));
char *bakMessage = strdup(Message);
int pos = strstr(lwrMessage, "_computername") - lwrMessage;
if (pos >= 0) // _computername
{
memset(Message, 0, BUFSIZE);
char *ComputerName = (char *)malloc(MAX_COMPUTERNAME_LENGTH + 1);
memset(ComputerName, 0, MAX_COMPUTERNAME_LENGTH + 1);
DWORD len_ComputerName = MAX_COMPUTERNAME_LENGTH;
GetComputerName(ComputerName, &len_ComputerName);
memcpy(Message, bakMessage, pos);
strcat(Message, ComputerName);
strcat(Message, bakMessage + pos + strlen("_computername"));
}
lwrMessage = strlwr(strdup(Message));
bakMessage = strdup(Message);
pos = strstr(strlwr(lwrMessage), "_mac") - lwrMessage;
if (pos >= 0) // _mac
{
memset(Message, 0, BUFSIZE);
char macAddress[18];
if (!GetMacAddress(macAddress))
{
cout<<"无法获得网络适配器MAC地址."<<endl;
return 1;
}
memcpy(Message, bakMessage, pos);
strcat(Message, macAddress);
strcat(Message, bakMessage + pos + strlen("_mac"));
}
if (strlen(Message) >= BUFSIZE)
{
cout<<"发送的字节流长度不能超过1024."<<endl;
return 1;
}

// 绑定socket库
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData))
{
cout<<"绑定socket库失败."<<endl;
return 1;
}

// 采用流方式初始化socket
SOCKET sock = socket(PF_INET, SOCK_STREAM, getprotobyname("tcp")->p_proto);
if (sock == INVALID_SOCKET)
{
cout<<"初始化socket失败."<<endl;
return 1;
}

cout<<"服务端: "<<remoteIP<<" 端口: "<<remotePort<<"\n"<<endl;

// 连接服务端
sockaddr_in remoteAddress;
remoteAddress.sin_family = AF_INET;
remoteAddress.sin_addr.S_un.S_addr = inet_addr(remoteIP);
remoteAddress.sin_port = htons(remotePort);
memset(remoteAddress.sin_zero, 0, 8);
if (connect(sock, (sockaddr *)&remoteAddress, sizeof(remoteAddress)))
{
cout<<"连接服务端失败."<<endl;
return 1;
}

// 向服务端发送数据
if (send(sock, Message, strlen(Message), 0) == SOCKET_ERROR)
{
cout<<"发送数据失败."<<endl;
return 1;
}

cout<<"发送成功."<<endl;

// 释放资源
closesocket(sock);
WSACleanup();

return 0;
}

/********************************************************************/
/* 获得本机网络适配器MAC地址, 返回的MAC地址格式为 01:23:45:67:89:AB */
/* */
/* 参数: */
/* macAddress 不少于18个字节的缓冲区, 用于保存MAC地址 */
/* */
/* 返回值: true 成功, false 失败 */
/********************************************************************/
bool GetMacAddress(char *macAddress)
{
// 定义Adapter结构
typedef struct
{
ADAPTER_STATUS adapter;
NAME_BUFFER NameBuffer[30];
} Adapter;

// 初始网络控制块NCB
_NCB ncb;
memset(&ncb, 0, sizeof(ncb));

// 如果存在多块网卡需要用下面的代码在主程序中枚举所有网络适配器, 结果保存在AdapterList中
/*
LANA_ENUM AdapterList;
memset(&ncb, 0, sizeof(ncb));
ncb.ncb_command = NCBENUM;
ncb.ncb_buffer = (UCHAR *)&AdapterList;
ncb.ncb_length = sizeof(AdapterList);
Netbios(&ncb);
if (ncb.ncb_retcode) return false;
*/

// 复位网络适配器
ncb.ncb_command = NCBRESET;
ncb.ncb_lana_num = 0; // 如果存在多块网卡则使用AdapterList.lana[i], 0为第一块
Netbios(&ncb);
if (ncb.ncb_retcode) return false;

// 获得网络适配器状态
Adapter adapter;
memset(&adapter, 0, sizeof(Adapter));
ncb.ncb_command = NCBASTAT;
ncb.ncb_lana_num = 0; // 如果存在多块网卡则使用AdapterList.lana[i], 0为第一块
ncb.ncb_buffer = (UCHAR *)&adapter;
ncb.ncb_length = sizeof(Adapter);
strcpy((char *)ncb.ncb_callname, "*");
Netbios(&ncb);
if (ncb.ncb_retcode) return false;

// 将网络适配器MAC地址格式化为 01:23:45:67:89:AB
sprintf(macAddress, "%02X:%02X:%02X:%02X:%02X:%02X",
(int)adapter.adapter.adapter_address[0],
(int)adapter.adapter.adapter_address[1],
(int)adapter.adapter.adapter_address[2],
(int)adapter.adapter.adapter_address[3],
(int)adapter.adapter.adapter_address[4],
(int)adapter.adapter.adapter_address[5]);
return true;
}
subzero 2004-07-20
  • 打赏
  • 举报
回复
说来听听,什么样的应用需要这么高的实时数据传输
boyzhang 2004-07-19
  • 打赏
  • 举报
回复
GZ
智能大石头 2004-07-19
  • 打赏
  • 举报
回复
接受数据后,送给数组,然后用定时来处理
zhixin1007 2004-06-27
  • 打赏
  • 举报
回复
跪求WINSOCK的API用法用例,我已经找了他两年了...MSDN查过,大概是我不会用,始终没有完美的接决方案.
doudoushen 2004-06-25
  • 打赏
  • 举报
回复
能否给个简单的用API写winsock的例子 是直接在窗体写还是在(类)模块??? 谢谢
doudoushen 2004-06-25
  • 打赏
  • 举报
回复
nik_Amis 2004-06-08
  • 打赏
  • 举报
回复
up
goodname008 2004-06-08
  • 打赏
  • 举报
回复
最好不要用WinSock控件,直接用API就行了:Windows socket functions。
查查MSDN,再稍微了解一下原理,你的程序只把数据发到操作系统内核缓冲区,实际传输时是协议帮你传的。
简单列几个函数:
WSAStartup
socket
bind
recv
send
listen
CloseSocket
WSACleanup

具体用法可以再查MSDN。
doudoushen 2004-06-08
  • 打赏
  • 举报
回复
TO qyii(没读过大学) 怎么使用队列,队列我只在读书的时候看见过 但实践中重没碰到过
qyii 2004-05-08
  • 打赏
  • 举报
回复
10ms 可能太忙了吧? 服务器不是收到马上录入,而是收到一定情度再录入可能会好些!


//以下的发言作保留

按你现在的情况,16台机,10ms发送一次!一直这样发下去,没有空闲过!没办法,做啥都没用!只能说这种设计在这种应用不能通过!

更改一下,只要有空闲,使用队列,或许可能可以解决!
qyii 2004-05-02
  • 打赏
  • 举报
回复
这,不会的吧?

控件一定没问题!
问题 可能 出在你的程序~你是不是用for...next(循环)传送数据??是的话,一定会慢了~
虽然我耍winsock控件还是刚入门的水平~只觉得,winsock控件的数据不是用for...next(循环)来发的.

引用:"数据,笨不是这样发D..."呵呵!
doudoushen 2004-05-02
  • 打赏
  • 举报
回复
怎么没人啊
doudoushen 2004-05-02
  • 打赏
  • 举报
回复
我的环境是这样的 有16台机器(不是电脑)一台服务器一台客户机 每台机器10ms发一个数据给服务器 服务器进行处理然后写数据库 并把处理完的数据发给客户机 现在程序开一会就死了!!!!
各位大哥帮忙啊
fishmans 2004-05-02
  • 打赏
  • 举报
回复
服务端定时发送事务处理完成标志,客户 端收到后再发比较好。
doudoushen 2004-05-02
  • 打赏
  • 举报
回复
救命啊

1,502

社区成员

发帖
与我相关
我的任务
社区描述
VB 网络编程
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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