我是socket编程的新手,我正在努力了解它的操作htons().我已经在互联网上一样阅读一些教程这和这一个实例.但我无法理解究竟htons()是什么.我尝试了以下代码:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main( int argc, char *argv[] )
{
int sockfd, newsockfd, portno, clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
int n;
/* First call to socket() function */
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
perror("ERROR opening socket");
exit(1);
}
/* Initialize socket structure */
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = 5001;
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = …Run Code Online (Sandbox Code Playgroud) 我想将我的软件版本嵌入到我的代码中,然后使用类似-vor之类的命令从程序二进制文件中检索它--version.作为示例,一些GNU/Linux软件二进制文件在命令行中提供-v或-V参数时打印其版本信息,ls以此为例:
$ ls --version
ls (GNU coreutils) 8.13
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Run Code Online (Sandbox Code Playgroud)
是否有约定或标准这样做?我试图搜索这些信息,但由于我不知道正确的术语,我的搜索仅导致版本控制howto.软件代码是用C++语言编写的,如果它有助于更好地解决问题.
在我的客户端代码中,我按照以下步骤连接到套接字:
创建套接字
sockDesc = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)
Run Code Online (Sandbox Code Playgroud)连接(在发生故障时重试'x'时间)
connect(sockDesc, (sockaddr *) &destAddr, sizeof(destAddr))
Run Code Online (Sandbox Code Playgroud)
(填写后填写destAddr)
使用socket进行send()/ recv()操作:
send(sockDesc, buffer, bufferLen, 0)
recv(sockDesc, buffer, bufferLen, 0)
Run Code Online (Sandbox Code Playgroud)close() 套接字描述符并退出
close(sockDesc)
Run Code Online (Sandbox Code Playgroud)如果在send()/ recv()连接断开期间,我发现我可以通过返回到步骤2进行连接.
这个解决方案好吗?我应该关闭套接字描述符并返回步骤1吗?
另一个我无法理解的有趣观察是当我停止我的echo服务器并启动客户端时.我创建了一个Socket(步骤1)并且调用connect()失败(正如预期的那样)但是我继续打电话connect(),比方说,10次.重试5次后,我启动服务器并connect()成功完成.但在send()通话期间它收到SIGPIPE错误.我想知道:
1)每次connect()失败都需要创建一个新套接字吗?根据我的理解,只要我没有在套接字上执行任何send()/ recv()它就像新的一样好,我可以重用它fd来进行connect()调用.
2)我不明白SIGPIPE服务器启动并connect()成功后收到的原因.
正如Charles Bailey 在这个问题中所回答的那样,当对象类型很大但是什么样的对象被认为是大的时候,应该考虑常量引用?
编辑: 确定提供更多可用于提供更具体答案的数据我决定在此描述中添加一个真实世界的问题.
假设我们有一个像这样的对象:
typedef struct dipl {
quint16 __id;
quint16 __pos;
quint16 __len;
} data;
Run Code Online (Sandbox Code Playgroud)
我们有另一个这样的对象:
class bidipl
{
public:
bidipl();
quint8 id();
void setid(quint8 __id);
void appenddipl(dipl __dipl);
private:
qint8 _M_id;
dipllist _M_dipllist;
};
Run Code Online (Sandbox Code Playgroud)
哪里dipllist是typedef QList<dipl> dipllist;.对象dipl和bidipl创建一次,但每分钟可以访问100次.那么我们应该如何传递dipl给append函数呢?
void appenddipl(dipl __dipl);
Run Code Online (Sandbox Code Playgroud)
要么
void appenddipl(const dipl& __dipl);
Run Code Online (Sandbox Code Playgroud) #include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main()
{
struct sockaddr_in addr;
int fd, cnt,ret;
char ch = 'y',msg[] ="How are you";
if ((fd=socket(AF_INET,SOCK_DGRAM,0)) < 0) {
printf("Error: socket");
exit(1);
}
printf("\nDone socket\n");
/* set up destination address */
memset(&addr,0,sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_addr.s_addr=inet_addr("128.88.143.113");
addr.sin_port=htons(9090);
ret=connect(fd,(struct sockaddr *)&addr,sizeof(addr));
perror("Connect:");
while(ch == 'y'){
cnt = send(fd,msg,sizeof(msg),0);
if(cnt < 0)
perror("send:");
printf("\nNumber of bytes sent = %d , \n",cnt);
printf("Continue (y/n)\n");
scanf(" %c",&ch);
} …Run Code Online (Sandbox Code Playgroud) 我在Linux上的一个项目使用了阻塞套接字.事情发生非常连续,所以非阻塞只会让事情变得更复杂.无论如何,我发现经常一个recv()调用返回-1与errno设置为EAGAIN.
该man页面只是真正提到非阻塞套接字发生这种情况,这是有道理的.如果没有阻塞,则套接字可能可用,也可能不可用,因此您可能需要重试.
什么会导致阻塞套接字发生?我可以做些什么来避免它吗?
目前,我处理它的代码看起来像这样(我在错误时抛出异常,但除此之外它是一个非常简单的包装器recv()):
int ret;
do {
ret = ::recv(socket, buf, len, flags | MSG_NOSIGNAL);
} while(ret == -1 && errno == EAGAIN);
if(ret == -1) {
throw socket_error(strerror(errno));
}
return ret;
Run Code Online (Sandbox Code Playgroud)
这甚至是正确的吗?这种EAGAIN情况经常受到打击.
编辑:我注意到的一些可能相关的事情.
我在套接字上设置了读取超时setsockopts(),但设置为30秒.这种EAGAIN情况经常发生在每30秒一次.修正我的调试有缺陷,EAGAIN不会像我想象的那样经常发生.也许是超时触发.
为了连接,我希望能够连接超时,所以我暂时将套接字设置为非阻塞.该代码如下所示:
int error = 0;
fd_set rset;
fd_set wset;
int n;
const SOCKET sock = m_Socket;
// set the socket …Run Code Online (Sandbox Code Playgroud)我在Windows环境的编程方面有一些经验,但我需要在BeagleBone Black上开发一个"Kiosk"(我听说这是正确的名称).我是Linux的新手,也是我将要使用的工具的新手.直到最近几个月,我一起开发VB6并且C++Builder只开发了.
现在我有Eclipse,MinGW并wxWidgets在我的Windowns 7 64位PC和BeagleBone Black上启动Debian 7.8 LXDE.
我需要设置一个工具链来编译BeagleBone Black.我非常努力地读了至少一百页,但我还是没弄明白.
从本网站我了解到可以从Windows编译Linux,这可能是完美的解决方案.如果不可能的话,我已经有一台运行Ubuntu的虚拟机(但我可以根据需要更改)准备好Eclipse和其他东西安装.
我仍然对使用/构建的工具链感到迷茫.这个网站似乎已经建立了一个工具链,但是没有任何迹象表明从哪里开始.我知道我现在应该wxWidgets使用这些工具编译,但我不确定,而且我也不想弄乱我在Windows中当前的工作设置,因为我错过了一个开关或路径.
我看到这个问题是多次被问到的,但我找不到一个最新的问题,所以我再问一遍.
如何使用工具链来编译GUI应用程序,从Windows使用Eclipse,MinGW以及wxWidget运行Debian的BeagleBone Black和LXDE?
我有一个问题,每次在不同的主题中更新主题.因此,每当主题被更新时,它相应地用新信息更新观察者.但是,如果观察者列表很长,则需要一些时间来更新所有观察者.想想一个经常更新的主题.当主题正在更新观察者时,"主题"对象被锁定,因此不能由不同的线程更新.这将为主题创建信息流量或导致信息丢失.
您是否知道如何在多线程环境中处理这些问题?另外,有人可以推荐一些关于C++并行编程的书吗?
我读的man页面,我的理解是,如果write()失败,并设置errno到EAGAIN或者EINTR,我可以执行write()了,所以我想出了下面的代码:
ret = 0;
while(ret != count) {
write_count = write(connFD, (char *)buf + ret, count);
while (write_count < 0) {
switch(errno) {
case EINTR:
case EAGAIN:
write_count = write(connFD, (char *)buf + ret, count -ret);
break;
default:
printf("\n The value of ret is : %d\n", ret);
printf("\n The error number is : %d\n", errno);
ASSERT(0);
}
}
ret += write_count;
}
Run Code Online (Sandbox Code Playgroud)
我正在表演read()和write()插座,read() …
我想创建一个对象,std::array<T, N>但问题是我只能使用返回constexpr类型的函数,否则编译器会抱怨。这里的问题是我需要根据另一个数组的大小来计算该数组的长度,可能是这样的:
template <typename T>
struct DataLength
{
template <typename iter>
size_t maxPossibleLength(iter begin, iter end)
{
size_t m_size = 0;
while (begin != end) {
m_size = m_size << 8 | std::numeric_limits<T>::max(); /* 0xff for uchar*/
begin++;
}
return m_size;
}
}
Run Code Online (Sandbox Code Playgroud)
我如何转换这个函数的输出,以便我可以使用它而不是N?