Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.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
C Linux套接字:第二次读取()在本地主机上失败_C_Linux_Sockets - Fatal编程技术网

C Linux套接字:第二次读取()在本地主机上失败

C Linux套接字:第二次读取()在本地主机上失败,c,linux,sockets,C,Linux,Sockets,我有一个服务器,它确认一个命令,然后发送数据。它与命令行配合良好:echo“show version”| nc-q1 127.0.0.1 5000给出: Command received: show version Beta 我有一个客户端,它的行为应该与命令行测试完全相同,但是它挂起在第二个read()调用上,除非我在不同的服务器上运行它。我对unix域套接字也有同样的问题,只是它们偶尔会工作 为什么它只能在本地主机上失败 客户端来源 #include <unistd.h> #i

我有一个服务器,它确认一个命令,然后发送数据。它与命令行配合良好:
echo“show version”| nc-q1 127.0.0.1 5000
给出:

Command received: show version
Beta
我有一个客户端,它的行为应该与命令行测试完全相同,但是它挂起在第二个
read()
调用上,除非我在不同的服务器上运行它。我对unix域套接字也有同样的问题,只是它们偶尔会工作

为什么它只能在本地主机上失败

客户端来源

#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#define ERR_FAIL_CONNECT        -1
#define ERR_SOCK_SELECT         -2
#define ERR_SOCK_READ           -3
#define ERR_SOCK_WRITE          -3
#define ERR_SOCK_REMOTE_CLOSED  -4

int tcpConnect (char *ipAddr, int port);
int sendCommand (char *buf, int bufSize);
int readWithTimeout (int sock, char *buf, int bufSize, struct timeval *timeout);

int main() {
    char buf[64];
    int nBytes;

    strcpy(buf, "show version");
    nBytes = sendCommand(buf, sizeof(buf));
    printf("Response: %s\n", buf);

    return 0;
}

int sendCommand (char *buf, int bufSize) {
    int apiSock;
    int nBytes = ERR_SOCK_SELECT;
    int len;
    struct timeval timeout;

    apiSock = tcpConnect("127.0.0.1", 5000);
    if (!apiSock) return ERR_FAIL_CONNECT;

    len = strlen(buf);
    nBytes = write(apiSock, buf, len);
    if (nBytes < 0) {
        perror("ERROR writing to socket");
        nBytes = ERR_SOCK_WRITE;
    }
    else if (nBytes < len) {
        fprintf(stderr, "Command truncated at %d/%d\n", nBytes, len);
        nBytes = ERR_SOCK_WRITE;
    }
    else {
        timeout.tv_sec = 3;
        timeout.tv_usec = 0;
        nBytes = readWithTimeout(apiSock, buf, bufSize, &timeout);
        if (nBytes > 0) {
            timeout.tv_sec = 20;
            timeout.tv_usec = 0;
            nBytes = readWithTimeout(apiSock, buf, bufSize, &timeout);
        }
    }
    close(apiSock);

    return nBytes;
}

int tcpConnect (char *ipAddr, int port) {
    struct sockaddr_in addr;
    int sock;

    sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock == -1) {
        perror("ERROR: Could not create TCP socket");
        return 0;
    }

    addr.sin_addr.s_addr = inet_addr(ipAddr);
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);

    if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
        perror("ERROR: Could not connect");
        return 0;
    }

    return sock;
}

int readWithTimeout (int sock, char *buf, int bufSize, struct timeval *timeout) {
    int res;
    int nBytes = ERR_SOCK_SELECT;
    fd_set set;

    fprintf(stderr, "readWithTimeout(sock=%d, buf='%s', bufSize=%d, timeout{tv_sec=%d, tv_usec=%d})\n",
            sock, buf, bufSize, timeout->tv_sec, timeout->tv_usec);
    FD_ZERO(&set);
    FD_SET(sock, &set);

    res = select(sock+1, &set, NULL, NULL, timeout);
    if (res < 0) perror("ERROR waiting for data");
    else if (res == 0) fprintf(stderr, "Timed out waiting for data\n");
    else {
        nBytes = read(sock, buf, bufSize);
        if (nBytes < 0) {
            perror("ERROR reading from socket");
            nBytes = ERR_SOCK_READ;
        }
        else if (nBytes == 0) {
            fprintf(stderr, "Remote end closed socket\n");
            shutdown(sock, 2);
            close(sock);
            nBytes = ERR_SOCK_REMOTE_CLOSED;
        }
    }

    return nBytes;
}
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#define TCP_PORT 5000
#define BUF_SIZE    512

int readCommand(int clientSockFd);
void myWrite (int fileDescriptor, const void *buf, size_t nbytes);

int main (void) {
    socklen_t client_len;
    int optval;
    int flags;
    struct sockaddr_in serv_addr, client_addr;

    int serverSockFd;
    int clientSockFd;

    fd_set set;
    struct timeval timeout;
    int rv;

    serverSockFd = socket(AF_INET, SOCK_STREAM, 0);
    if(serverSockFd < 0) perror("ERROR opening socket");

    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(TCP_PORT);

    if(bind(serverSockFd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
        perror("Unable to bind TCP socket");
    }

    listen(serverSockFd, 5);
    client_len = sizeof(client_addr);
    flags = fcntl(serverSockFd, F_GETFL, 0);
    if (flags < 0) perror("Unable to read TCP socket flags");
    flags = flags|O_NONBLOCK;
    fcntl(serverSockFd, F_SETFL, flags);

    // Wait for client connections
    while(1) {
        clientSockFd = accept(serverSockFd, (struct sockaddr *) &client_addr, &client_len);
        if(clientSockFd < 0) {
            usleep(50000);
            continue;
        }

        //After connected, inner loop to read and write multiple packages
        while(1) {
            FD_ZERO(&set);
            FD_SET(clientSockFd, &set);
            timeout.tv_sec = 15;
            timeout.tv_usec = 0;

            rv = select(clientSockFd+1, &set, NULL, NULL, &timeout);
            if(rv == -1) {
                perror("select");
                continue;
            }
            else if(rv == 0) {
                printf("TCP timeout, closing client connection.\n");
                shutdown(clientSockFd, 2);
                break;
            }

            if (!readCommand(clientSockFd)) break;
        }

        close(clientSockFd);
    }

    close(serverSockFd);

    return 0;
}

int readCommand(int sock) {
    int nBytes;
    int len;
    char inBuf[BUF_SIZE];
    char outBuf[BUF_SIZE];

    nBytes = read(sock, inBuf, BUF_SIZE);
    if(nBytes < 0) perror("ERROR reading from TCP socket");
    else if(nBytes == 0) {
        printf("Client closed TCP socket\n");
        shutdown(sock, 2);
        return nBytes;
    }
    else {
        // Acknowledge command
        len = sprintf(outBuf, "Command received: %s", inBuf);
        if (write(sock, outBuf, len+1) < 0) {
            perror("ERROR writing to TCP socket");
        }

        // Send response data
        if (!strncmp("show version", inBuf, 12)) strcpy(outBuf, "Beta");
        else strcpy(outBuf, "Invalid command");
        if (write(sock, outBuf, strnlen(outBuf, BUF_SIZE-1)+1) < 0) {
            perror("ERROR writing to TCP socket");
        }
    }

    return nBytes;
}
#包括
#包括
#包括
#包括
#包括
#包括
#定义ERR\u FAIL\u CONNECT-1
#定义ERR_SOCK_SELECT-2
#定义ERR_SOCK_READ-3
#定义ERR_SOCK_WRITE-3
#定义ERR\u SOCK\u REMOTE\u CLOSED-4
int TCP连接(字符*ipAddr,int端口);
int sendCommand(字符*buf,int bufSize);
int readWithTimeout(int sock,char*buf,int bufSize,struct timeval*timeout);
int main(){
char-buf[64];
整数字节;
strcpy(buf,“显示版本”);
nBytes=sendCommand(buf,sizeof(buf));
printf(“响应:%s\n”,buf);
返回0;
}
int sendCommand(字符*buf,int bufSize){
int apiSock;
int nBytes=错误存储选择;
内伦;
结构timeval超时;
apiSock=TCP连接(“127.0.0.1”,5000);
如果(!apiSock)返回ERR\u FAIL\u CONNECT;
len=strlen(buf);
nBytes=写入(apiSock、buf、len);
如果(n字节<0){
perror(“写入套接字时出错”);
n字节=错误写入;
}
else if(n字节0){
timeout.tv_sec=20;
timeout.tv_usec=0;
nBytes=readWithTimeout(apiSock、buf、bufSize和timeout);
}
}
关闭(apiSock);
返回n字节;
}
int TCP连接(字符*ipAddr,int端口){
地址中的结构sockaddr\u;
int袜子;
sock=socket(AF\u INET,sock\u STREAM,0);
如果(sock==-1){
perror(“错误:无法创建TCP套接字”);
返回0;
}
addr.sin\u addr.s\u addr=inet\u addr(ipAddr);
addr.sin_family=AF_INET;
地址SINU port=htons(端口);
if(connect(sock,(struct sockaddr*)&addr,sizeof(addr))<0){
perror(“错误:无法连接”);
返回0;
}
返回袜子;
}
int readWithTimeout(int sock、char*buf、int bufSize、struct timeval*timeout){
国际关系;
int nBytes=错误存储选择;
fd_集;
fprintf(stderr,“readWithTimeout(sock=%d,buf='%s',bufSize=%d,timeout{tv\u sec=%d,tv\u usec=%d})\n”,
sock,buf,bufSize,超时->电视秒,超时->电视秒;
FD_零位(&set);
FD_套装(袜子和套装);
res=select(sock+1,&set,NULL,NULL,timeout);
if(res<0)perror(“等待数据的错误”);
如果(res==0)fprintf(stderr,“等待数据超时”\n);
否则{
nBytes=读取(sock、buf、bufSize);
如果(n字节<0){
perror(“从套接字读取错误”);
n字节=错误存储读取;
}
else if(n字节==0){
fprintf(stderr,“远程端闭合套接字”\n);
停机(sock,2);
关闭(袜子);
n字节=错误\u套接字\u远程\u关闭;
}
}
返回n字节;
}
服务器源

#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#define ERR_FAIL_CONNECT        -1
#define ERR_SOCK_SELECT         -2
#define ERR_SOCK_READ           -3
#define ERR_SOCK_WRITE          -3
#define ERR_SOCK_REMOTE_CLOSED  -4

int tcpConnect (char *ipAddr, int port);
int sendCommand (char *buf, int bufSize);
int readWithTimeout (int sock, char *buf, int bufSize, struct timeval *timeout);

int main() {
    char buf[64];
    int nBytes;

    strcpy(buf, "show version");
    nBytes = sendCommand(buf, sizeof(buf));
    printf("Response: %s\n", buf);

    return 0;
}

int sendCommand (char *buf, int bufSize) {
    int apiSock;
    int nBytes = ERR_SOCK_SELECT;
    int len;
    struct timeval timeout;

    apiSock = tcpConnect("127.0.0.1", 5000);
    if (!apiSock) return ERR_FAIL_CONNECT;

    len = strlen(buf);
    nBytes = write(apiSock, buf, len);
    if (nBytes < 0) {
        perror("ERROR writing to socket");
        nBytes = ERR_SOCK_WRITE;
    }
    else if (nBytes < len) {
        fprintf(stderr, "Command truncated at %d/%d\n", nBytes, len);
        nBytes = ERR_SOCK_WRITE;
    }
    else {
        timeout.tv_sec = 3;
        timeout.tv_usec = 0;
        nBytes = readWithTimeout(apiSock, buf, bufSize, &timeout);
        if (nBytes > 0) {
            timeout.tv_sec = 20;
            timeout.tv_usec = 0;
            nBytes = readWithTimeout(apiSock, buf, bufSize, &timeout);
        }
    }
    close(apiSock);

    return nBytes;
}

int tcpConnect (char *ipAddr, int port) {
    struct sockaddr_in addr;
    int sock;

    sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock == -1) {
        perror("ERROR: Could not create TCP socket");
        return 0;
    }

    addr.sin_addr.s_addr = inet_addr(ipAddr);
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);

    if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
        perror("ERROR: Could not connect");
        return 0;
    }

    return sock;
}

int readWithTimeout (int sock, char *buf, int bufSize, struct timeval *timeout) {
    int res;
    int nBytes = ERR_SOCK_SELECT;
    fd_set set;

    fprintf(stderr, "readWithTimeout(sock=%d, buf='%s', bufSize=%d, timeout{tv_sec=%d, tv_usec=%d})\n",
            sock, buf, bufSize, timeout->tv_sec, timeout->tv_usec);
    FD_ZERO(&set);
    FD_SET(sock, &set);

    res = select(sock+1, &set, NULL, NULL, timeout);
    if (res < 0) perror("ERROR waiting for data");
    else if (res == 0) fprintf(stderr, "Timed out waiting for data\n");
    else {
        nBytes = read(sock, buf, bufSize);
        if (nBytes < 0) {
            perror("ERROR reading from socket");
            nBytes = ERR_SOCK_READ;
        }
        else if (nBytes == 0) {
            fprintf(stderr, "Remote end closed socket\n");
            shutdown(sock, 2);
            close(sock);
            nBytes = ERR_SOCK_REMOTE_CLOSED;
        }
    }

    return nBytes;
}
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#define TCP_PORT 5000
#define BUF_SIZE    512

int readCommand(int clientSockFd);
void myWrite (int fileDescriptor, const void *buf, size_t nbytes);

int main (void) {
    socklen_t client_len;
    int optval;
    int flags;
    struct sockaddr_in serv_addr, client_addr;

    int serverSockFd;
    int clientSockFd;

    fd_set set;
    struct timeval timeout;
    int rv;

    serverSockFd = socket(AF_INET, SOCK_STREAM, 0);
    if(serverSockFd < 0) perror("ERROR opening socket");

    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(TCP_PORT);

    if(bind(serverSockFd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
        perror("Unable to bind TCP socket");
    }

    listen(serverSockFd, 5);
    client_len = sizeof(client_addr);
    flags = fcntl(serverSockFd, F_GETFL, 0);
    if (flags < 0) perror("Unable to read TCP socket flags");
    flags = flags|O_NONBLOCK;
    fcntl(serverSockFd, F_SETFL, flags);

    // Wait for client connections
    while(1) {
        clientSockFd = accept(serverSockFd, (struct sockaddr *) &client_addr, &client_len);
        if(clientSockFd < 0) {
            usleep(50000);
            continue;
        }

        //After connected, inner loop to read and write multiple packages
        while(1) {
            FD_ZERO(&set);
            FD_SET(clientSockFd, &set);
            timeout.tv_sec = 15;
            timeout.tv_usec = 0;

            rv = select(clientSockFd+1, &set, NULL, NULL, &timeout);
            if(rv == -1) {
                perror("select");
                continue;
            }
            else if(rv == 0) {
                printf("TCP timeout, closing client connection.\n");
                shutdown(clientSockFd, 2);
                break;
            }

            if (!readCommand(clientSockFd)) break;
        }

        close(clientSockFd);
    }

    close(serverSockFd);

    return 0;
}

int readCommand(int sock) {
    int nBytes;
    int len;
    char inBuf[BUF_SIZE];
    char outBuf[BUF_SIZE];

    nBytes = read(sock, inBuf, BUF_SIZE);
    if(nBytes < 0) perror("ERROR reading from TCP socket");
    else if(nBytes == 0) {
        printf("Client closed TCP socket\n");
        shutdown(sock, 2);
        return nBytes;
    }
    else {
        // Acknowledge command
        len = sprintf(outBuf, "Command received: %s", inBuf);
        if (write(sock, outBuf, len+1) < 0) {
            perror("ERROR writing to TCP socket");
        }

        // Send response data
        if (!strncmp("show version", inBuf, 12)) strcpy(outBuf, "Beta");
        else strcpy(outBuf, "Invalid command");
        if (write(sock, outBuf, strnlen(outBuf, BUF_SIZE-1)+1) < 0) {
            perror("ERROR writing to TCP socket");
        }
    }

    return nBytes;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义TCP_端口5000
#定义BUF_大小512
int readCommand(int clientSockFd);
void myWrite(int fileDescriptor,const void*buf,size\u t nbytes);
内部主(空){
socklen_u t client_len;
int optval;
国际旗帜;
服务地址、客户端地址中的结构sockaddr\u;
int-serverSockFd;
int clientSockFd;
fd_集;
结构timeval超时;
int-rv;
serverSockFd=socket(AF\u INET,SOCK\u STREAM,0);
if(serverSockFd<0)perror(“错误打开套接字”);
bzero((char*)&serv_addr,sizeof(serv_addr));
serv_addr.sin_family=AF_INET;
serv_addr.sin_addr.s_addr=INADDR_ANY;
serv_addr.sin_port=htons(TCP_端口);
if(bind(serverSockFd,(struct sockaddr*)&serv_addr,sizeof(serv_addr))<0{
perror(“无法绑定TCP套接字”);
}
听(5);
客户地址=sizeof(客户地址);
flags=fcntl(serverSockFd,F_GETFL,0);
如果(标志<0)或(“无法读取TCP套接字标志”);
标志=标志| O|非块;
fcntl(服务器sockfd、F_SETFL、标志);
//等待客户端连接
而(1){
clientSockFd=accept(serverSockFd,(struct sockaddr*)&client\u addr,&client\u len);
if(clientSockFd<0){
美国LEEP(50000);
持续
}
//连接后,内部循环读取和写入多个包
而(1){
FD_零位(&set);
FD_集(clientSockFd,&SET);
timeout.tv_sec=15;
timeout.tv_usec=0;
rv=select(clientSockFd+1,&set,NULL,NULL,&timeout);
如果(rv==-1){
佩罗(“选择”);
持续
}
否则如果(rv==0){
printf(“TCP超时,关闭客户端连接。\n”);
关闭(clientSockFd,2);
打破
}
如果(!readCommand(clientSockFd))中断;
}
关闭(clientSockFd);
}
关闭(serverSockFd);
返回0;
}
int readCommand(int sock){
整数字节;
内伦;
字符inBuf[BUF_大小];
字符大小[BUF_SIZE];
n字节=读取(sock、inBuf、BUF_大小);
如果(n字节<0)perror(“从TCP套接字读取错误”);
else if(n字节==0){
printf(“客户端关闭的TCP套接字”);
停机(sock,2);
返回n字节;
}
否则{
//确认命令
len=sprintf(exputf,“收到的命令:%s”,i