2016-12-03 84 views
0

我是C編程的新手,我一直在嘗試編寫一個程序向自己發送消息,接收消息併發回消息。我發現一個客戶端和服務器程序的example,基本上只是複製它,試圖做一些改變。該程序不僅崩潰,而且輸出「你的信息」。代碼中沒有任何地方是字符串「你的信息」,那麼它怎麼可能每次都輸出呢?C程序在嘗試使用套接字時輸出奇怪的「ur消息」

我很抱歉粘貼大量的代碼,我只是不知道問題出在哪裏,我不想留下任何可能相關的東西。任何幫助將不勝感激,謝謝。

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

#include <pthread.h> 

char *write_buffer_to_port(char *host, int portno); 
char *listen_on_port(int portno); 
void* listen_thread(void *arg); 
char *buffer_a; 
char *buffer_b; 

int main(int argc, char *argv[]) { 
    buffer_a = "test"; 
    buffer_b = ""; 
    pthread_t tid[2]; 
    pthread_create(&(tid[1]), NULL, &listen_thread, NULL); 
    printf("%s",write_buffer_to_port("localhost", 5737)); 
} 

char *write_buffer_to_port(char *host, int portno) { 
    int sockfd, n; 

    struct sockaddr_in serv_addr; 
    struct hostent *server; 

    sockfd = socket(AF_INET, SOCK_STREAM, 0); 
    if (sockfd < 0) exit(1); 

    server = gethostbyname(host); 
    if (server == NULL) exit(2); 

    bzero((char *) &serv_addr, sizeof(serv_addr)); 
    serv_addr.sin_family = AF_INET; 
    bcopy((char *)server->h_addr, 
    (char *)&serv_addr.sin_addr.s_addr, 
    server->h_length); 
    serv_addr.sin_port = htons(portno); 
    if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) exit(3); 
    n = write(sockfd, buffer_a, strlen(buffer_a)); 
    if (n < 0) exit(4); 

    n = read(sockfd, &buffer_a, 255); 
    if (n < 0) exit(5); 
    close(sockfd); 
    return (char *)buffer_a; 
} 

char *listen_on_port(int portno) { 
    int sockfd, newsockfd, clilen; 

    struct sockaddr_in serv_addr, cli_addr; 
    int n; 
    sockfd = socket(AF_INET, SOCK_STREAM, 0); 
    if (sockfd < 0) exit(1); 
    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(portno); 
    if (bind(sockfd, (struct sockaddr *) &serv_addr, 
         sizeof(serv_addr)) < 0) exit(2); 
    listen(sockfd,5); 
    clilen = sizeof(cli_addr); 
    newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen); 
    if (newsockfd < 0) exit(3); 
    //bzero(buffer_a,256); 
    n = read(newsockfd,&buffer_b,255); 
    if (n < 0) exit(4); 
    //printf("Here is the message: %s\n",(char *)&buffer_b); 
    n = write(newsockfd,"I got your message",18); 
    if (n < 0) exit(5); 
    return (char *)&buffer_b; 
} 

void* listen_thread(void *arg) { 
    printf("rcvd: %s\n",listen_on_port(5737)); 
    return NULL; 
} 
+0

我總是想知道爲什麼你們的新手們開始使用這種複雜的東西(多線程客戶端/服務器)。如果(試圖成爲?)成爲一名機械工程師,你不會從火箭開始,即使搭乘飛機,但也許是用自行車或出發卡......,不是嗎? – alk

+0

@alk誠然,但我覺得很難被激勵去建立我不想要的東西。爲什麼不在一個有趣的項目上工作,並採取必要的切線,在途中學習你需要的東西?這可能需要很長時間才能建立,但是一天結束時,你會得到一個很酷的項目和一些相當不錯的技能。而且我並不是新手編程,只是C. – Jake

回答

2

「你的信息」是「我收到你的信息」的結尾。

您沒有正確使用buffer_abuffer_b。你宣佈他們的方式,他們是指向char。當您執行read(fd, &buffer_b, 255)時,您正在讀取指針buffer_b佔用的內存,而不是讀入某個緩衝區。

如果要讀入緩衝區,則需要將緩衝區聲明爲有空間供您讀入的對象,或者將其聲明爲指針並調用malloc爲其分配內存。如果你聲明緩衝區爲char buffer_a[256],你將能夠讀入它們。該聲明保留256個字節,並且buffer_a是該存儲器的開始地址。然後您可以執行read(fd, buffer_a, sizeof(buffer_a))來讀取緩衝區。

我看到你正在初始化buffer_a爲一個你要寫的字符串,如果你將它聲明爲一個數組,那麼你仍然可以這樣做,但是隻寫這個字符串本身會更簡單。

+0

好的。原始代碼是緩衝[256],但我改變了它,因爲我無法打印或返回它。我如何有一個函數返回一個char [256]? – Jake

+1

該函數將返回'char *'('char'數組的名稱就像一個常量'char *')。 –

0

您正在使用未分配的緩衝區, char * buffer_a; char * buffer_b; 所以要解決它要麼分配(malloc)它在主或聲明他們作爲數組。