Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
select等待在套接字中写入的奇怪行为_C_Sockets - Fatal编程技术网

select等待在套接字中写入的奇怪行为

select等待在套接字中写入的奇怪行为,c,sockets,C,Sockets,我只想在连接套接字后等待,看看是否可以写入它。 所以我创建并连接我的套接字,并使用“选择”来完成这项工作,除非。。。这不正确 这是我的密码: int SocketToBox(char boxIp[INET6_ADDRSTRLEN], int port) { struct sockaddr_in boxAddress; int sock = -1; if ((sock = socket(AF_INET, SOCK_STREAM |

我只想在连接套接字后等待,看看是否可以写入它。 所以我创建并连接我的套接字,并使用“选择”来完成这项工作,除非。。。这不正确

这是我的密码:

int SocketToBox(char boxIp[INET6_ADDRSTRLEN], int port)
{
    struct sockaddr_in boxAddress;
    int                sock      = -1;

    if ((sock = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0)) == -1) {
        printf("%s : socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0) : errno = '%s'.\n", __func__, strerror(errno));
        return (-1);
    }

    memset(&boxAddress, 0, sizeof(boxAddress));
    boxAddress.sin_family = AF_INET;
    boxAddress.sin_port = htons(port);
    if (inet_pton(AF_INET, boxIp, &boxAddress.sin_addr) != 1) {
        printf("%s : inet_pton(AF_INET, boxIp<'%s'>, &boxAddress.sin_addr) : errno = '%s'.\n", __func__, boxIp, strerror(errno));
        close(sock);
        return (-1);
    }

    if (connect(sock, (struct sockaddr *)&boxAddress, sizeof(boxAddress)) == -1) {
        if (errno != EINPROGRESS) {
            printf("%s : connect(sock<%d>, (struct sockaddr *)&boxAddress, sizeof(boxAddress)) : errno = '%s'.\n", __func__, sock, strerror(errno));
            close(sock);
            return (-1);
        }
    }
    return (sock);
}



int main(void)
{
    int    sock;
    fd_set writeFdSet;
    char   *message   = "Hello World !";

    if ((sock = SocketToBox("192.192.192.192", 2000)) == -1) {
        printf("%s : SocketToBox(\"192.192.192.192\", 2000) : callstack.\n", __func__);
        return (1);
    }

    FD_ZERO(&writeFdSet);
    FD_SET(sock, &writeFdSet);

    if (select(sock + 1, NULL, &writeFdSet, NULL, NULL) == -1) {
        printf("%s : select(sock<%d> + 1, NULL, &writeFdSet, NULL, NULL) : errno = '%s'.", __func__, sock, strerror(errno));
        return (1);
    }

    if (FD_ISSET(sock, &writeFdSet)) {
        printf("socket UP.\n");

        if (send(sock, message, strlen(message), MSG_DONTWAIT) == -1) {
            printf("%s : send(sock<%d>, message<'%s'>, strlen(message)<%zu>, MSG_DONTWAIT) : errno '%s'.\n", __func__, sock, message, strlen(message), strerror(errno));
            return (1);
        }
        printf("Message sended.\n");
    } else {
        printf("socket DOWN.\n");
    }

    FD_ZERO(&writeFdSet);
    if (sock == -1) {
        close(sock);
    }
    return (0);
}
int-SocketToBox(char-boxIp[INET6\u-ADDRSTRLEN],int-port)
{
boxAddress中的结构sockaddr_;
int sock=-1;
if((sock=socket(AF_INET,sock_STREAM | sock_NONBLOCK,0))=-1){
printf(“%s:socket(AF_INET,SOCK_STREAM | SOCK_NONBLOCK,0):errno='%s'.\n',uu func_u,strerror(errno));
返回(-1);
}
memset(&boxAddress,0,sizeof(boxAddress));
boxAddress.sin_family=AF_INET;
boxAddress.sin_port=htons(端口);
if(inet\u pton(AF\u inet、boxIp和boxAddress.sin\u addr)!=1){
printf(“%s:inet\u pton(AF\u inet,boxIp,&boxAddress.sin\u addr):errno='%s'.\n“,\u func\u,boxIp,strerror(errno));
关闭(袜子);
返回(-1);
}
if(connect(sock,(struct sockaddr*)&boxAddress,sizeof(boxAddress))=-1){
if(errno!=EINPROGRESS){
printf(“%s:connect(sock,(struct sockaddr*)和boxAddress,sizeof(boxAddress)):errno='%s'.\n',__func_;,sock,strerror(errno));
关闭(袜子);
返回(-1);
}
}
返回(短袜);
}
内部主(空)
{
int袜子;
fd_集writeFdSet;
char*message=“你好,世界!”;
如果((sock=SocketToBox(“192.192.192.192”,2000))=-1){
printf(“%s:SocketToBox(\'192.192.192\',2000):调用堆栈。\n”,\uu func\uuu);
申报表(1);
}
FD_ZERO(&writeFdSet);
FD_集(sock和writeFdSet);
if(选择(sock+1,NULL,&writeFdSet,NULL,NULL)=-1){
printf(“%s:select(sock+1,NULL,&writeFdSet,NULL,NULL):errno=“%s.”,_uufunc,sock,strerror(errno));
申报表(1);
}
if(FD_ISSET(sock和writeFdSet)){
printf(“套接字启动。\n”);
如果(发送(sock、message、strlen(message)、MSG_DONTWAIT)=-1){
printf(“%s:send(sock,message,strlen(message),MSG_DONTWAIT):错误号“%s”。\n“,\u函数,sock,message,strlen(message),strerror(errno));
申报表(1);
}
printf(“消息已发送。\n”);
}否则{
printf(“套接字关闭。\n”);
}
FD_ZERO(&writeFdSet);
如果(sock==-1){
关闭(袜子);
}
返回(0);
}
以及我的输出:

socket UP.
main : send(sock<3>, message<'Hello World !'>, strlen(message)<13>, MSG_DONTWAIT) : errno 'Connection timed out'.
socketup。
main:send(sock、message、strlen(message)、MSG_DONTWAIT):errno“连接超时”。
我错过了什么? 选择return1,我也不明白!为什么是1而不是0? 为什么我的套接字在发送失败时被select标记为“可写”? 我可以向您保证,我不能从以下位置ping 192.192.192。

成功时,
select()
pselect()
返回三个返回的描述符集中包含的文件描述符的数量

这就是
select
函数为您返回
1
的原因:它返回集合中的一个描述符集


对于第二个问题,请参见手册页:

如果可以执行相应的I/O操作(例如,
read(2)
而不阻塞,或者足够小的
write(2)
),则认为文件描述符已准备就绪

将监视
writefds
中的文件,以查看是否有空间可供写入(尽管较大的写入操作仍可能会阻塞)


因此,
select
将告诉您的是描述符内部缓冲区中有可用空间,它没有说明数据是否可以实际发送。

因为写入未连接的套接字不会阻塞-这是select唯一能保证您的。

我建议您从阅读开始,这应该可以解释这两种行为。谢谢。。。真正地我已经阅读了此选择手册页,但我不理解其行为。我将试着这样回答我的问题:为什么我故意不连接任何东西的套接字被select标记为可写?
SOCK\u NONBLOCK
MSG\u DONTWAIT
是非标准的(即非POSIX)。这是什么操作系统?对不起,我忘了这么说:它是Debian。你可能想在:
http://stackoverflow.com/questions/10204134/tcp-connect-error-115-operation-in-progress-what-is-the-cause
这是关于同样的问题。好的,谢谢。我一开始读《人》时根本不明白这一点,但这是有道理的。操作系统只是说他有一个准备写入的缓冲区,而不是连接了套接字。我想我必须找到另一种方法来知道插座是否真的连接了。谢谢