1、UDP 並發伺服器,大家幫忙看一看!該如何解決
UDP2000個客戶端左右 並發
單個數據包最大512位元組
Internet 10MB帶寬
要求效率(盡可能快,盡可能少丟包),這種情況下用哪種通訊模型比較有優勢!
想用IOCP,因為和select模型相比,這個稍微熟悉一點,也在項目中用過,不過是TCP的。
有兩個問題,大家懂得的幫忙給指導一下:
是否可以理解為UDP模式下,一次recvfrom 只對應一次sendto。
2.能否對服務端的套接字同時投遞多個WsaRecvFrom,能否在多個線程中同時投遞WsaSendTo和WsaRecvFrom。
------解決方案--------------------------------------------------------
-------------------------------------
等不到,包被截斷了。
2.能否對服務端的套接字同時投遞多個WsaRecvFrom,能否在多個線程中同時投遞WsaSendTo和WsaRecvFrom。
--------------------------
其實,我個人認為對udp而言,不用iocp也可以滿足。 首先sendto都是立即完成的,無需非同步操作。而recvfrom可以只需阻塞一個線程就夠了,不需要重疊操作。
------解決方案--------------------------------------------------------
用UDX協議最可靠,效率高,開發簡單,非開源。
UDT開源,對於你這種2000客戶,夠用,開源。
------解決方案--------------------------------------------------------
1.sendto 10k,接受部分要麼收到10k,要麼全部丟失,不會出現部分收到的情況。
------解決方案--------------------------------------------------------
-------------------------------------
在區域網可以,公網,一般1K也收不到。
2.能否對服務端的套接字同時投遞多個WsaRecvFrom,能否在多個線程中同時投遞WsaSendTo和WsaRecvFrom。
--------------------------完全可以
------解決方案--------------------------------------------------------
1.如果UDP數據在傳輸過程中被分包,則你需要對數據包進行標識,已確保獲取的包完整。一次recvfrom並不對應一次sendto,考慮UDP不可靠傳輸的因素。
2.不可以,因為sendto和recvfrom都是對同一個資源Socket進行操作。如果在多個線程中對同一個資源進行操作,如果不加鎖的情況下,會非常可怕的。而且,如果你加鎖了,其實還不如單線程操作。
按照你的需求最好還是採用UDP,不過可以考慮組播。
2.API調用完全沒有問題。但是接到的數據可能和發送的數據次序不一樣,這本身是UDP亂序特性決定了的。而且你發送方可能是多線程,從API層面來說,這些調用都是可以的,完全沒有問題。但是給你接收方處理帶來一系列問題。
2、udp伺服器怎麼創建多個socket描述符
DP Server程序 1、編寫UDP Server程序的步驟 (1)使用socket()來建立一個UDP socket,第二個參數為SOCK_DGRAM。 (2)初始化sockaddr_in結構的變數,專並賦值。sockaddr_in結構定義:屬 struct sockaddr_in { uint8_t sin_len; sa_family_t sin_family
3、如何搭建udp echo server
具體配置過程:
1、打開STM32CubeMX,並選擇好相應的晶元。文中的晶元為STM32F207VCT6,選擇後如下圖:
2、配置RCC時鍾、ETH、PA8以及使能LWIP;
由於此處我們的開發板硬體上為RMII方式,因此選擇ETH-RMII,若有同志的開發板為MII方式,請參考MII的配置方法,此處只針對RMII;
RCC選擇外部時鍾源,另外勾選MCO1,軟體會自動將PA8配置為MCO1模式,該引腳對於RMII方式很重要,用於為PHY晶元提供50MHz時鍾;
使能LWIP;
3、時鍾樹的相關配置,必須保證MCO1輸出為50Mhz,如果這個頻率不對會導致PHY晶元無法工作;
我這里因為晶元為207VCT6,為了使MCO1輸出為50Mhz,做了PLL倍頻參數的一些調整,總體如下:(同志們配置時可根據自己的晶元靈活配置,但需保證MCO1的輸出為50Mhz)
4、ETH、LWIP、RCC相關參數設置;
至此,比較重要的都在前面了,但是還有一點仍需要注意,即PA8引腳輸出速度,幾次不成功都是因為這個引腳沒注意。
後續的參數設置可以根據同志們自己的需求分別設置,這里給出我的設置供參考;
ETH參數保持默認,但中斷勾選一下;
LWIP參數設置如下:(因為我這里是配置UDP伺服器,IP選擇靜態分配)
5、生成工程,做最後的函數修改;
給生成的工程添加UDP伺服器的初始化以及埠綁定等相關函數;
我這里直接將之前的官方常式中的UDP伺服器文件加進來,如下:
之後將.c文件添加到用戶程序,主函數添加Udp的.h頭文件;如下:(udp文件的具體內容在後面給出)
6、主函數還需要添加一下幾個函數,在這里不對函數作用及實現原理講解,僅做添加說明。
附:udp_echoserver相關文件內容(該文件為官方的示常式序,版權歸官方,此處做轉載)
udp_echoserver.c的內容如下:
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "lwip/pbuf.h"
#include "lwip/udp.h"
#include "lwip/tcp.h"
#include
#include
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define UDP_SERVER_PORT 7 /* define the UDP local connection port */
#define UDP_CLIENT_PORT 7 /* define the UDP remote connection port */
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
void udp_echoserver_receive_callback(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port);
/* Private functions ---------------------------------------------------------*/
/**
* @brief Initialize the server application.
* @param None
* @retval None
*/
void udp_echoserver_init(void)
{
struct udp_pcb *upcb;
err_t err;
/* Create a new UDP control block */
upcb = udp_new();
if (upcb)
{
/* Bind the upcb to the UDP_PORT port */
/* Using IP_ADDR_ANY allow the upcb to be used by any local interface */
err = udp_bind(upcb, IP_ADDR_ANY, UDP_SERVER_PORT);
if(err == ERR_OK)
{
/* Set a receive callback for the upcb */
udp_recv(upcb, udp_echoserver_receive_callback, NULL);
}
}
}
/**
* @brief This function is called when an UDP datagrm has been received on the port UDP_PORT.
* @param arg user supplied argument (udp_pcb.recv_arg)
* @param pcb the udp_pcb which received data
* @param p the packet buffer that was received
* @param addr the remote IP address from which the packet was received
* @param port the remote port from which the packet was received
* @retval None
*/
void udp_echoserver_receive_callback(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
{
/* Connect to the remote client */
udp_connect(upcb, addr, UDP_CLIENT_PORT);
/* Tell the client that we have accepted it */
udp_send(upcb, p);
/* free the UDP connection, so we can accept new clients */
udp_disconnect(upcb);
/* Free the p buffer */
pbuf_free(p);
}
udp_echoserver.h的內容如下:
#ifndef __ECHO_H__
#define __ECHO_H__
void udp_echoserver_init(void);
#endif /* __MINIMAL_ECHO_H */
7、至此,所有的工作完成,編譯工程,下載至開發板。由於udp_echoserver中綁定的埠號為7,這里我們通過測試工具測試網路的功能,
4、如何建立udp通信的server端和client端
伺服器端代碼
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int sock;
//sendto中使用的對方地址
struct sockaddr_in toAddr;
//在recvfrom中使用的對方主機地址
struct sockaddr_in fromAddr;
int recvLen;
unsigned int addrLen;
char recvBuffer[128];
sock = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
if(sock < 0)
{
printf("創建套接字失敗了.\r\n");
exit(0);
}
memset(&fromAddr,0,sizeof(fromAddr));
fromAddr.sin_family=AF_INET;
fromAddr.sin_addr.s_addr=htonl(INADDR_ANY);
fromAddr.sin_port = htons(4000);
if(bind(sock,(struct sockaddr*)&fromAddr,sizeof(fromAddr))<0)
{
printf("bind() 函數使用失敗了.\r\n");
close(sock);
exit(1);
}
while(1){
addrLen = sizeof(toAddr);
if((recvLen = recvfrom(sock,recvBuffer,128,0,(struct sockaddr*)&toAddr,&addrLen))<0)
{
printf("()recvfrom()函數使用失敗了.\r\n");
close(sock);
exit(1);
}
if(sendto(sock,recvBuffer,recvLen,0,(struct sockaddr*)&toAddr,sizeof(toAddr))!=recvLen){
printf("sendto fail\r\n");
close(sock);
exit(0);
}
return 0;
}
}
5、我想用c++寫一個UDP的客服器與伺服器實現文件傳輸,並且伺服器可以為多
對C++的UDP編程不太了解,我以前用C#寫過傳文件的
因為不是可靠連接,所以傳送的順序可能會亂還可能丟包,所以你要自己寫一個簡單的協議,
比如,服務端發送 我要給你發文件,客戶端回答,好的我准備好了你傳吧
然後,服務端把文件發成小塊 做一個自定義結構,包含文件塊的一些校驗信息、塊大小、序號之類的發給客戶端,然後客戶端收到之後檢查沒有錯誤後告訴服務端收到了,如果有錯則告訴服務端重發,如果服務端在特定時間沒有收到回復,則重新發送這個數據塊
最後文件結束時發送一個結束標志
多客戶端時,則需要有服務端定義一個列表,記錄所有客戶端信息,做統一管理,這個最好用線程,每一個客戶端分配一個線程來處理
大概就這樣吧,需要的知識比較多比較雜,你可以多找一些資料
你看看
http://keencard.blog.163.com/blog/static/10237173020092210262750/
6、想用C#做個UDP伺服器,求大神指點。。
對第一個問題,你可以這樣:做一個while(true)循環,循環內UdpClient 在不停Receive ,接收到 byte[] ReceivedByte 以後,馬上建立一個線程去處理接收到的數據,你進入處理ReceivedByte 的線程時,不要直接對ReceivedByte 處理,復制一份過去,這里是繼續Receive 的,至於你有幾種格式什麼的,與UdpClient 的Receive無關了,那是線程做的事情了,while體內繼續下一次Receive。而UDP面向無連接,不存在最大客戶端數量問題。
第二個問題:你在啟動線程同時,ReceivedByte ,IP作為參數進去就可以了
同時建立一個string數組,把你要記錄的數據都寫到string數組里(寫到string數組之後,同時寫一下txt文件),再用一個定時器定時把string數組里的東西更新到你要顯示的控制項裡面去。
不存在專門的函數做這些,都要自己實現,
對於線程帶參數 格式如下:
new Thread(delegate(){dotask(recivebytecopy,ipaddress)}).start();
dotask實現:
void dotask(byte[] recive,string ipaddress)
{
//你要做的事情
}
7、用C#開發一個UDP伺服器
網上歷程有的來是啊
無非就自是
IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 10002);
Socket command_sock_query =new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
command_sock_query.Bind(ipep);
然後是發送和接收
command_sock_query.SendTo(sendbuf, sendbuf.Length, SocketFlags.None, remoteIpEndPoint);
int recv = command_sock_query.ReceiveFrom(recv_data, ref Remote);
但是伺服器一般會寫多線程。這就是UDP的一個弊端了。只有阻塞在接收介面了,一旦接收到數據就要開啟新的線程,會導致一個客戶端創建很多線程
建議TCP寫伺服器吧,在連接那監聽,創建新線程。
8、c++編寫UDP客戶/伺服器程序,要求:使用udp服務實現客戶端與伺服器交互信息.
服務端與客戶端很大差異:
服務端接收多個客戶請示,客戶端只有一個客戶,
處理也不一樣。
你C++要選擇一個支持窗體的版本,如C++BUILDER,VC++等
9、UDP伺服器是做什麼用的?
UDP伺服器,就是首發數據,進行數據處理的。與TCP不同的是不用建立連接,直接調用recvfrom來收包。
開始就是基本的socket初始化地址什麼的。
要求多個線程處理客戶端命令,那recvfrom收包後,考慮把客戶端的地址信息保存,便於sendto,對接收的數據包,交給線程進行處理,每個線程可以向一塊共享內存、隊列里寫入收到的數據和對應的客戶端信息,每次寫的時候對這塊共享資源加鎖,多個線程對共享資源讀是加鎖,讀完解鎖,並開始處理數據。
處理完,用sendto發回去。
不是什麼大項目。小程序而已。
10、CS1.6架設伺服器問題~ 關於路由器UDP映射得到外網IP和埠? 請教一下具體如何操作?萬分感謝
源地址來: 就是你的路由自器IP地址 你的公網IP
源埠: 到達你路由器的埠 比如說 27015 CS伺服器埠
目的地址:就是你架CS伺服器的IP地址
埠: CS伺服器埠
協議是:udp
還有,你在本機上修改這些好象是沒用的,必須在路由器上設置。
在本機設置的這些,只適合電話線-貓-電腦的這種情況!