簡體   English   中英

未在TCP客戶端/服務器程序中接收消息

[英]Not receiving messages in TCP client/server program

我正在嘗試實現TCP客戶端和TCP服務器。 我能夠建立連接,但是當我從客戶端發送消息時,服務器未收到該消息,是的,我確實查看了以前的帖子,並且存在很多類似的問題。 我確實關注了他們,但仍然遇到相同的錯誤。 我收到的錯誤來自服務器端:

recv: Socket operation on non-socket

這是我的代碼。 如果可以的話,請讓我知道我在做錯什么,對此我將不勝感激。 我認為服務器實施中存在問題。

服務器:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT 3490
#define BACKLOG 10

int main()
{
    struct sockaddr_in server;
    struct sockaddr_in dest;
    int status,socket_fd, client_fd,num;
    socklen_t size;

    char buffer[10240];
    memset(buffer,0,sizeof(buffer));
    int yes = 1;

    if ((socket_fd = socket(AF_INET, SOCK_STREAM, 0))== -1) {
        fprintf(stderr, "Socket failure!!\n");
        exit(1);
    }

    if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
        perror("setsockopt");
        exit(1);
    }

    memset(&server, 0, sizeof(server));
    memset(&dest,0,sizeof(dest));
    server.sin_family = AF_INET;
    server.sin_port = htons(PORT);
    server.sin_addr.s_addr = INADDR_ANY; 
    if ((bind(socket_fd, (struct sockaddr *)&server, sizeof(struct sockaddr )))== -1)    { //sizeof(struct sockaddr) 
        fprintf(stderr, "Binding Failure\n");
        exit(1);
    }

    if ((listen(socket_fd, BACKLOG))== -1){
        fprintf(stderr, "Listening Failure\n");
        exit(1);
    }

    while(1) {
        size = sizeof(struct sockaddr_in);  

        if ((client_fd = accept(socket_fd, (struct sockaddr *)&dest, &size)==-1)) {
            //fprintf(stderr,"Accept Failure\n");
            perror("accept");
            exit(1);
        }

        printf("Server got connection from client %s\n", inet_ntoa(dest.sin_addr));
        //buffer = "Hello World!! I am networking!!\n";

        if ((num = recv(client_fd, buffer, 10239,0))== -1) {
            //fprintf(stderr,"Error in receiving message!!\n");
            perror("recv");
            exit(1);
        }   

        // num = recv(client_fd, buffer, sizeof(buffer),0);
        buffer[num] = '\0';
        printf("Message received: %s\n", buffer); 
        close(client_fd);   
        return 0;
        //close(socket_fd); 
    }    
}

客戶:

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

#define PORT 3490

int main(int argc, char *argv[])
{
    struct sockaddr_in server_info;
    struct hostent *he;
    int socket_fd,num;
    char *buffer;

    if (argc != 2) {
        fprintf(stderr, "Usage: client hostname\n");
        exit(1);
    }

    if ((he = gethostbyname(argv[1]))==NULL) {
        fprintf(stderr, "Cannot get host name\n");
        exit(1);
    }

    if ((socket_fd = socket(AF_INET, SOCK_STREAM, 0))== -1) {
        fprintf(stderr, "Socket Failure!!\n");
        exit(1);
    }

    memset(&server_info, 0, sizeof(server_info));
    server_info.sin_family = AF_INET;
    server_info.sin_port = htons(PORT);
    server_info.sin_addr = *((struct in_addr *)he->h_addr);
    if (connect(socket_fd, (struct sockaddr *)&server_info, sizeof(struct sockaddr))<0) {
        //fprintf(stderr, "Connection Failure\n");
        perror("connect");
        exit(1);
    }

    buffer = "Hello World!! I am networking!!\n";
    if ((send(socket_fd,buffer, sizeof(buffer),0))== -1) {
        fprintf(stderr, "Failure Sending Message\n");
        close(socket_fd);
        exit(1);
    }
    else {
        printf("Message being sent: %s\n",buffer);
    }

    close(socket_fd);   
}

我在gdb下運行服務器,並在調用accept()之后發現client_fd為0。 這是無效的套接字fd,因此我查看了該行代碼,並注意到右括號是錯誤的:

if ((client_fd = accept(socket_fd, (struct sockaddr *)&dest, &size)==-1)) {

應該:

if ((client_fd = accept(socket_fd, (struct sockaddr *)&dest, &size))==-1) {

否則,它將先進行比較,然后將比較分配給client_fd,而您要分配套接字,然后再進行比較。

為了避免這種令人沮喪的錯誤,通常認為最佳做法是不要將賦值放在“ if”語句中。 我建議改為:

client_fd = accept(...);
if (client_fd < 0) { ... }

同樣,在客戶端中,對send()的調用使用“ sizeof(buffer)”。 'buffer'是一個char *,指針的大小為4(在32位系統上),因此僅發送'Hell'。 要發送完整的字符串,請使用“ strlen(buffer)”代替要發送的金額。

您的第一個問題是括號放錯了位置。

if ((client_fd = accept(socket_fd, (struct sockaddr *)&dest, &size)==-1)) {

實際上應該是

if ((client_fd = accept(socket_fd, (struct sockaddr *)&dest, &size))==-1) {

如您目前所擁有的, client_fd將被分配給accept()返回值和-1之間的相等性測試結果,因此,如果成功,它將始終為零。

這就是許多程序員避免在if語句中進行賦值的原因之一。 如果這樣寫

client_fd = accept(socket_fd, (struct sockaddr *)&dest, &size);
if (client_fd == -1) {

那么就不會發生錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM