UDP服务器如何设计

一个程序员的修炼之路 2010-12-18 06:35:19
我查阅了一些资料,

我首先尝试了一种方法:
(一)
udp srv:
socket();
bind(port);
while(1)
{
if(recvConnectReQ)
{
AfxBeginThread(taskThd);
}
if(StopEvent)
break;
}
--------------
taskThd:
socket();
bind(a unused port);
send msg to the client socket: I am Here, u can cantact with me
begin the task;
closesocket();
--------------
udp client:
socket();
bind();
sendConnectReq;
if recved the I am Here msg, transmit data to that socket!
task over;

我尝试写完了,模型我认为小处理情况下没问题;
但是我发现了新的问题,当udp编程中重新创建新的socket进行通信,局域网测试会丢包,这个问题还没有解决(有知道的朋友)
这个问题我已经发过帖子,还未解决,可帮忙看下:http://topic.csdn.net/u/20101120/14/030a669b-a3a9-4a33-a3b6-29effff6ff38.html

(二)还有一种是最简单的,直接用一个socket,循环接收所有数据包,然后进行处理
但这种方式,如何去处理数据呢?


还有什么完成端口等,希望大家给点思路
...全文
289 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
a469367940 2010-12-20
  • 打赏
  • 举报
回复
楼主太厉害,初看你的代码,在想如果有150个客户端,我看这个程序铁定死了,150个现场会卡死程序。要写个IO模型,用完成端口吧。
hurryboylqs 2010-12-19
  • 打赏
  • 举报
回复
可以实现类似TCP一样每一个连接一个socket
这样对于交互频繁的逻辑就这么做的
UDP与TCP不同的就是无连接的,不可靠的,不按顺序的
这些靠你的应用来保证,UDP尽最大努力给你传输数据包。
UDP是抢占式的
hurryboylqs 2010-12-19
  • 打赏
  • 举报
回复
你这代码,不是这么写的
你自己实现一个udp session吧
  • 打赏
  • 举报
回复
上面一个是客户端 ,下面一个是服务器端:
#include <stdio.h>
#include <winsock2.h>
#define MAX_SIZE 64000
#define CONNECT_NUM 5
#pragma comment(lib,"WS2_32.lib")

int main()
{
WSADATA wsd;
char sendBuff[MAX_SIZE+1];
char buff[MAX_SIZE+1];
int connectCount = 0;
strcpy(sendBuff,"OK!");
if (WSAStartup(MAKEWORD(1,1),&wsd) != 0)
{
printf("failed! WL! \n");
return 1;
}


SOCKET sListen = socket(AF_INET,SOCK_DGRAM,0);
SOCKADDR_IN local;
local.sin_family = AF_INET;
local.sin_port = htons(6000);
local.sin_addr.s_addr = inet_addr("192.168.1.5");
bind(sListen,(SOCKADDR *)&local,sizeof(local));

int nRecvBuf=64*1024;
setsockopt(sListen,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));
int nSendBuf=64*1024;
setsockopt(sListen,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int));

int count = 0;
SOCKADDR_IN client;
int iAddrSize = sizeof(client);
memset(&client,0,sizeof(client));



SOCKET sL = socket(AF_INET,SOCK_DGRAM,0);
SOCKADDR_IN local2;
local2.sin_family = AF_INET;
local2.sin_port = htons(6500);
local2.sin_addr.s_addr = inet_addr("192.168.1.5");
bind(sL,(SOCKADDR *)&local2,sizeof(local));
while(true)
{
int ret = recvfrom(sL,buff,MAX_SIZE,0,(SOCKADDR *)&client,&iAddrSize);
printf("count: %d ,%d \n",count++,ret);
}
system("pause");
return 0;
}


  • 打赏
  • 举报
回复
刚没贴上
#include <stdio.h>
#include <iostream.h>
#include <WINSOCK2.H>

#define MAX_SIZE 1000
#define DEFAULT_MSG "I am a good man!"
#define DWCOUNT 100
#pragma comment(lib,"WS2_32")


int main()
{
WSADATA wsd;
SOCKET sClient;
char buff[MAX_SIZE+1];
char revBuff[MAX_SIZE];
int ret,i;
SOCKADDR_IN server;
WSAStartup(MAKEWORD(1,1),&wsd);
strcpy(buff,DEFAULT_MSG);

sClient = socket(AF_INET,SOCK_DGRAM,0);
server.sin_family = AF_INET;
server.sin_port = htons(6000);
server.sin_addr.s_addr = inet_addr("192.168.1.5");
int nRecvBuf=64*1024; //接收缓冲区设置为64k
setsockopt(sClient,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));

int nSendBuf=64*1024; //发送缓冲区设置为64K
setsockopt(sClient,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int));

int w = sendto(sClient,"connect",strlen("connect"),0,(SOCKADDR *)&server,sizeof(SOCKADDR_IN));

server.sin_port = htons(6500);
connect(sClient,(SOCKADDR *)&server,sizeof(SOCKADDR_IN));
for (i = 0; i < DWCOUNT; i++)
{
sprintf(buff,"%d\n",i);
printf("%s\n",buff);
send(sClient,buff,MAX_SIZE,0);
}
closesocket(sClient);
WSACleanup();
system("pause");
return 0;
}


  • 打赏
  • 举报
回复
[Quote=引用 5 楼 hurryboylqs 的回复:]

最好用connect函数将套接字bind到目标地址上
connect会在内核抛弃所有来自非指定地址指定端口的数据
[/Quote]

您有兴趣可以看下 这是我简化后的代码

//服务器
#include <stdio.h>
#include <winsock2.h>
#define MAX_SIZE 64000
#define CONNECT_NUM 5
#pragma comment(lib,"WS2_32.lib")

int main()
{
WSADATA wsd;
char sendBuff[MAX_SIZE+1];
char buff[MAX_SIZE+1];
int connectCount = 0;
strcpy(sendBuff,"OK!");
if (WSAStartup(MAKEWORD(1,1),&wsd) != 0)
{
printf("failed! WL! \n");
return 1;
}


SOCKET sListen = socket(AF_INET,SOCK_DGRAM,0);
SOCKADDR_IN local;
local.sin_family = AF_INET;
local.sin_port = htons(6000);
local.sin_addr.s_addr = inet_addr("192.168.1.5");
bind(sListen,(SOCKADDR *)&local,sizeof(local));

int nRecvBuf=64*1024;
setsockopt(sListen,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));
int nSendBuf=64*1024;
setsockopt(sListen,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int));

int count = 0;
SOCKADDR_IN client;
int iAddrSize = sizeof(client);
memset(&client,0,sizeof(client));



SOCKET sL = socket(AF_INET,SOCK_DGRAM,0);
SOCKADDR_IN local2;
local2.sin_family = AF_INET;
local2.sin_port = htons(6500);
local2.sin_addr.s_addr = inet_addr("192.168.1.5");
bind(sL,(SOCKADDR *)&local2,sizeof(local));
while(true)
{
int ret = recvfrom(sL,buff,MAX_SIZE,0,(SOCKADDR *)&client,&iAddrSize);
printf("count: %d ,%d \n",count++,ret);
}
system("pause");
return 0;
}



//客户端
#include <stdio.h>
#include <iostream.h>
#include <WINSOCK2.H>

#define MAX_SIZE 1000
#define DEFAULT_MSG "I am a good man!"
#define DWCOUNT 100
#pragma comment(lib,"WS2_32")


int main()
{
WSADATA wsd;
SOCKET sClient;
char buff[MAX_SIZE+1];
char revBuff[MAX_SIZE];
int ret,i;
SOCKADDR_IN server;
WSAStartup(MAKEWORD(1,1),&wsd);
strcpy(buff,DEFAULT_MSG);

sClient = socket(AF_INET,SOCK_DGRAM,0);
server.sin_family = AF_INET;
server.sin_port = htons(6000);
server.sin_addr.s_addr = inet_addr("192.168.1.5");
int nRecvBuf=64*1024; //接收缓冲区设置为64k
setsockopt(sClient,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));

int nSendBuf=64*1024; //发送缓冲区设置为64K
setsockopt(sClient,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int));

int w = sendto(sClient,"connect",strlen("connect"),0,(SOCKADDR *)&server,sizeof(SOCKADDR_IN));

server.sin_port = htons(6500);
connect(sClient,(SOCKADDR *)&server,sizeof(SOCKADDR_IN));
for (i = 0; i < DWCOUNT; i++)
{
sprintf(buff,"%d\n",i);
printf("%s\n",buff);
send(sClient,buff,MAX_SIZE,0);
}
closesocket(sClient);
WSACleanup();
system("pause");
return 0;
}


当这种情况下 会出现 接收丢包问题
hurryboylqs 2010-12-19
  • 打赏
  • 举报
回复
最好用connect函数将套接字bind到目标地址上
connect会在内核抛弃所有来自非指定地址指定端口的数据
hurryboylqs 2010-12-19
  • 打赏
  • 举报
回复
没有代码看不出你问题在哪里,多查自己的代码吧
一定是你代码有问题导致的
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 hurryboylqs 的回复:]

可以实现类似TCP一样每一个连接一个socket
这样对于交互频繁的逻辑就这么做的
UDP与TCP不同的就是无连接的,不可靠的,不按顺序的
这些靠你的应用来保证,UDP尽最大努力给你传输数据包。
UDP是抢占式的
[/Quote]

这种方式我实现了 但还是有问题

就是这个链接里的:http://topic.csdn.net/u/20101120/14/030a669b-a3a9-4a33-a3b6-29effff6ff38.html


我在把问题表述一遍

服务器端:

(1)socket A 接收数据
(2)socket B 接收数据

客户端:
socket 发送数据给A地址
socket 发送数据给B地址

过程1 基本无丢包
而过程2 有丢包,我也问过老师了,老师也不是很清楚,有知道帮想想

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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