我想通過UDP發送一個字符串:"Jane Doe"
到內部網絡IP 192.168.0.4
到端口9000
。我通過Java通過UDP和TCP完成了這麼多次,但是現在我必須用標準C++庫來完成這項工作,而且我找不到任何只有人們無法使其工作的樣本。在C++中通過UDP發送字符串
我知道我必須將"Jane Doe"
編碼爲字節數組,然後只需打開套接字,將其打包成數據報併發送。
C++不是我的第一語言,這是我找不到的代碼的一小部分,我選擇了UDP,因爲它總是比TCP簡單得多。
我想通過UDP發送一個字符串:"Jane Doe"
到內部網絡IP 192.168.0.4
到端口9000
。我通過Java通過UDP和TCP完成了這麼多次,但是現在我必須用標準C++庫來完成這項工作,而且我找不到任何只有人們無法使其工作的樣本。在C++中通過UDP發送字符串
我知道我必須將"Jane Doe"
編碼爲字節數組,然後只需打開套接字,將其打包成數據報併發送。
C++不是我的第一語言,這是我找不到的代碼的一小部分,我選擇了UDP,因爲它總是比TCP簡單得多。
下面是一些示例Unix代碼。
如果這是Windows程序設計:
SOCKET
,而不是int
類型。closesocket
而不是close
#include <winsock2.h>
,而不是所有的UNIX頭#include <sys/types.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <memory.h>
#include <ifaddrs.h>
#include <net/if.h>
#include <errno.h>
#include <stdlib.h>
#include <iostream>
int resolvehelper(const char* hostname, int family, const char* service, sockaddr_storage* pAddr)
{
int result;
addrinfo* result_list = NULL;
addrinfo hints = {};
hints.ai_family = family;
hints.ai_socktype = SOCK_DGRAM; // without this flag, getaddrinfo will return 3x the number of addresses (one for each socket type).
result = getaddrinfo(hostname, service, &hints, &result_list);
if (result == 0)
{
//ASSERT(result_list->ai_addrlen <= sizeof(sockaddr_in));
memcpy(pAddr, result_list->ai_addr, result_list->ai_addrlen);
freeaddrinfo(result_list);
}
return result;
}
int main()
{
int result = 0;
int sock = socket(AF_INET, SOCK_DGRAM, 0);
char szIP[100];
sockaddr_in addrListen = {}; // zero-int, sin_port is 0, which picks a random port for bind.
addrListen.sin_family = AF_INET;
result = bind(sock, (sockaddr*)&addrListen, sizeof(addrListen));
if (result == -1)
{
int lasterror = errno;
std::cout << "error: " << lasterror;
exit(1);
}
sockaddr_storage addrDest = {};
result = resolvehelper("192.168.0.4", AF_INET, "9000", &addrDest);
if (result != 0)
{
int lasterror = errno;
std::cout << "error: " << lasterror;
exit(1);
}
const char* msg = "Jane Doe";
size_t msg_length = strlen(msg);
result = sendto(sock, msg, msg_length, 0, (sockaddr*)&addrDest, sizeof(addrDest));
std::cout << result << " bytes sent" << std::endl;
return 0;
}
@black它證明我的觀點沒有地方,至少很容易找到樣品和技術,以供參考。 – Yoda
@black - 今天有點挑剔不是我們嗎?如果這個答案完全錯誤或者會導致OP到一個糟糕的地方,你只應該回答一個答案。因爲您不喜歡編碼風格,因此不需要進行下調。如果你認爲你有一個更好的方法來回答OP的問題,那麼一定要發表一個答案。我甚至可能自己高興起來。我確實刪除了答案中的標題,以使其更加簡潔。 – selbie
@selbie明確指出:「如果您看到錯誤信息,請將其投票。」老實說,我以爲您從某處複製了代碼,因爲它沒有附帶任何文檔。此外,它確實包含了一些錯誤(實際上它不起作用):'sendto'需要6個參數,而不是4個。最後,從字符串文字到'char *'的轉換被棄用和不安全。 – edmz
這是很容易做到,如果你願意使用Boost庫。
這裏是代碼片段
#include "boost/asio.hpp"
using namespace boost::asio;
...
io_service io_service;
ip::udp::socket socket(io_service);
ip::udp::endpoint remote_endpoint;
socket.open(ip::udp::v4());
remote_endpoint = ip::udp::endpoint(ip::address::from_string("192.168.0.4"), 9000);
boost::system::error_code err;
socket.send_to(buffer("Jane Doe", 8), remote_endpoint, 0, err);
socket.close();
不應該緩衝區大小爲9?包括'\ 0'? –
如果您不想要字符串文字,則可以將字符放入:IPv4地址需要4個字節,其值介於0-255(含)之間。我們都知道2^8 = 256個可能的組合,8位= 1個字節 – dGRAMOP
我可能會使用升壓ASIO。如果我不能使用它(不管出於什麼原因),我可能會使用我在[CodeReview]上的一個答案(http://codereview.stackexchange.com/a/46354/489)中發佈的類。就目前而言,該代碼是Windows專用的,但幾乎只有Windows特有的部分是'socket_user'類和'#pragma comment lib'行(我認爲這些是唯一的部分,但我沒有測試過確定)。 –
@Yoda請選擇一個答案 –