Cc 套接字编程 select() 的第一个参数
Cc socket programming select()'s first argument
我一直在尝试用Linux进行一些网络编程,但我似乎又被卡住了。我似乎没有得到 select() 函数的第一个参数。 据我所知,它应该是最后一个制作的插座filedescriptor + 1
。 大多数情况下,最高的filedescriptor
包含数字 6。当我将filedescriptor
添加到fd_set
时,它突然变为 64——可能是因为它更改为fd_bytes
(如果我错了,请纠正我)。因此,6+1 似乎不适合选择语句,因为它一直在阻塞,但如果我从fd_set
获得fd_bytes
则不会。我对所有这些感到非常困惑,并希望就该主题提供一些建议,或者如果有人有的话,可以为sigio提供很好的教程,可以使事情变得更容易。
服务器.cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <boost/thread/thread.hpp>
#include <sys/time.h>
#include <sys/ioctl.h>
using namespace std;
void error(char *msg,int socket)
{
perror(msg);
close(socket);
exit(1);
}
int main(int argc, char** argv) {
int sockfd, newsockfd, portno, n;
socklen_t clilen;
fd_set readfds;
FD_ZERO(&readfds);
/*
* Sockfd, newsockfd contain values returned by the socket
* portno stores the port number on which the server accepts connections
* clilen stores the size of the address of the client
* n contains the amount of character written of read
*/
char buffer[256];
/* buffer contains the characters read from the socket*/
struct sockaddr_in serv_addr, cli_addr;
/*
* sockaddr_in contains an internet address
* serv_addr contains the servers address
* cli addr contains the clients address
*/
if(argc < 2)
{
fprintf(stderr,"ERROR no port provided");
exit(1);
}
/*
* error if no argument
*/
sockfd = socket(AF_INET,SOCK_STREAM,0);
int opt = 1;
ioctl(sockfd, FIONBIO, &opt);
if(sockfd < 0){
error("ERROR opening socket", sockfd);
}
/*
* socket() creates a new socket
* argument 1 contains the address domain
* argument 2 contains the socket type
* argument 3 contains the protocol should be 0
* socket() returns a reference for itself
*/
bzero((char*) &serv_addr, sizeof(serv_addr));
/* empty the serv_addr variable*/
portno = atoi(argv[1]);
/*converts the port argument from string to int*/
serv_addr.sin_family = AF_INET;
/*set the code for the address family*/
serv_addr.sin_port = htons(portno);
/*htons converts the portno to network bytes and gives it to the server address*/
serv_addr.sin_addr.s_addr = INADDR_ANY;
/*set the server ip to the ip of the running machine*/
if(bind(sockfd,(struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
error("ERROR on binding", sockfd);
/*
* bind() binds a socket to an address, in this case the
* addess of the current host
*/
listen(sockfd,5);
/*the listen system call allows the process to listen on the socket for
connections*/
clilen = sizeof(cli_addr);
do{
newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr, &clilen);
}while(newsockfd < 0);
/*
* accept() lets the system wait until a client connects to the server
*/
FD_SET(newsockfd,&readfds);
int sockcount = pselect(readfds.fds_bits[0] + 1,&readfds,NULL,NULL,NULL,NULL);
bzero(buffer,256);
n = read(newsockfd,buffer,255);
if(n < 0) error("ERROR reading from socket", sockfd);
printf("Here is the message: %s", buffer);
/*
* bzero empties the buffer
* read obviously reads data from the new socket descriptor
*/
n = write(newsockfd,"I got your message",18);
if(n < 0) error("ERROR writing to socket", sockfd);
close(sockfd);
return 0;
}
一些(或全部)代码可能没有意义,但这主要是因为我只是在测试代码的行为方式,然后让它多线程。上面的代码工作得更少:可以使用 telnet 或位于此处 http://www.linuxhowtos.org/C_C++/socket.htm 教程中的客户端进行测试。
我以前从未做过任何人readfds.fds_bits[0] + 1
。对于您的情况,您可以在pselect()
中使用newsockfd + 1
。
根据 pselect 的文档,如果您不提供 timespec 参数,它将阻塞,这就是代码中发生的情况。无论如何,您对 pselect 的调用实际上没有任何意义,因为 a) 您不会根据对 pselect 的调用结果做出任何决定,并且 b) 您随后立即调用 recv,这是一个阻塞调用。
相关文章:
- C++部分概念 id:显式模板规范顺序/第一个参数的特殊状态的原因是什么?
- 可变参数模板作为第一个参数
- 如何从第一个参数推断第二个参数类型?
- 候选构造函数(隐式复制构造函数)不可行:第一个参数需要 l 值
- 为什么 std::error_code 构造函数的第一个参数固定为 int
- 如何通过 std::apply 调用具有定义的第一个参数的可变参数模板函数?
- 如何获取指向 qsort 第一个参数的向量中第一项的指针?
- 如何在 Lua 回调中检测可选的第一个参数
- 如何让我的 strchr 函数同时将'const char'数组和'char'数组作为第一个参数?
- 在第一个参数上部分专用化模板
- 模板的C 功能将第一个参数设置为第二个参数为默认参数
- 如何获取指向函数第一个参数的指针
- 我可以使用use_lazy_terminal对获得3个参数懒惰的终端的第一个参数
- C++比较运算符重载中第一个参数为 null 时出现分段错误
- Cc 套接字编程 select() 的第一个参数
- 重载运算符:第一个参数对应左操作数,第二个参数对应右操作数
- 仅初始化c++11元组的第一个参数
- 我可以使用成员函数作为EnumWindows的第一个参数吗
- gdb只接受第一个参数
- 等键在 boost::unordered_multimap 中起作用:查询键是否保证是第一个参数