2017-01-25 304 views
0

我正在嘗試使用UNIX套接字和使用STREAM協議進行客戶端 - 服務器通信。UNIX套接字錯誤:在非套接字上的套接字操作

我的服務器正在運行的罰款,但我的客戶是行不通的。每當我嘗試發送或接收數據時,我都會收到一個錯誤:「在非套接字上的套接字操作」。我真的不知道它來自哪裏,因爲我的服務器非常相似,我沒有任何問題。我的服務器位於本地計算機(127.0.0.1)和端口5000.它是開放的並正在偵聽(我使用netstat命令進行了檢查)。

的代碼有:

#include <unistd.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <netdb.h> 
#include <errno.h> 

#define CHECK(ret, mes) if ((ret) == -1) {perror(mes); exit(-1);} 

#define STRING_LENGTH 250 

int createSocketINETClient(short mode, char *addr, short port) 
{ 
    int s; 
    struct sockaddr_in moi, server; 
    int moi_len, server_len; 

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

    memset(moi.sin_zero, 0, 8); 

    s = socket(AF_INET, mode, 0); 

    CHECK(s, "socket"); 

    moi_len = sizeof(moi); 

    CHECK(bind(s, (struct sockaddr*) &moi, moi_len), "bind"); 

    return s; 
} 

void infoSocket (int s) 
{ 
    struct sockaddr_in sock_addr; 
    socklen_t len = sizeof(sock_addr); 

    getsockname(s, (struct sockaddr*) &sock_addr, &len); 

    printf("Onfo of socket %d\n", s); 
    printf("\t IP : %s\n", inet_ntoa(sock_addr.sin_addr)); 
    printf("\t port : %d\n\n", ntohs(sock_addr.sin_port)); 
} 

int main() 
{ 
    int bytes; 
    int sock = createSocketINETClient(SOCK_STREAM, "0.0.0.0", 0); 
    struct sockaddr_in serveurSock; 
    int client = 0, clientSockLen = 0; 
    char message[] = "I am a message that is supposed to WORK !!!!\n"; 
    char fromServer[STRING_LENGTH] = ""; 
    infoSocket(sock); 


    serveurSock.sin_family = AF_INET; 
    serveurSock.sin_port = htons(5000); 
    serveurSock.sin_addr.s_addr = inet_addr("127.0.0.1"); 

    memset(serveurSock.sin_zero, 0, 8); 

    CHECK(connect(sock, (struct sockaddr*) &serveurSock, sizeof(serveurSock)), "connect"); 

    usleep(1000000); 

    CHECK((bytes = send(client, message, sizeof(message), 0)), "send"); 
    printf("Message sent to server : %d bytes, \"%s\"\n", bytes, message); 

    CHECK((bytes = recv(client, fromServer, sizeof(fromServer), 0)), "recv"); 
    printf("Message received from server : %d bytes, \"%s\"\n", bytes, fromServer); 

    close(client); 
    printf("Client released !\n\n"); 

    return 0; 
} 

我做了什麼錯?

編輯:誤差來源於此行:

CHECK((bytes = send(client, message, sizeof(message), 0)), "send"); 
+0

從哪個函數? – o11c

+0

我編輯帖子以包含錯誤的行,對不起 – ZamenWolk

+2

你正在使用'client',你應該使用'sock'。 – EJP

回答

0

您正在使用的「客戶端」變量作爲插座參數的SendTo()的時候,其實你應該使用「襪子」變量

你應該與strace程序,你可以看到以下內容:

connect(3, {sa_family=AF_INET, sin_port=htons(5000), sin_addr=inet_addr("127.0.0.1")}, 16) = 0 
nanosleep({tv_sec=1, tv_nsec=0}, NULL) = 0 
sendto(0, "I am a message that is supposed "..., 46, 0, NULL, 0) = -1 ENOTSOCK (Socket operation on non-socket) 

請注意,第一個sendto()參數爲0(默認情況下爲stdin文件描述符),實際上它應該爲3(請參見connect(...)line)

作爲旁註,除非有明確的理由這麼做(使用其他路由而不是默認路由,繞過某個防火牆規則等),否則不需要綁定()客戶端套接字。 OS將默認分配默認路由通過的網絡接口的IP地址和隨機空閒端口。

+0

謝謝!這是我看到的一個愚蠢的錯誤...我的意思是使用客戶端作爲套接字的變量,但我把它搞亂了。 – ZamenWolk

0

在發佈代碼初始化int client = 0然後我沒有看到你改變它。所以當你打電話給send(0, ...)你顯然會得到那個錯誤。已經@EJP在你的問題發表評論時提及

因爲它可以是一個錯字,因爲它看起來像你真的是打算用sock(因爲你連接它。connect(sock, ...)而不是呼叫clientsend