c - 使用 C 在服务器端读取从客户端发送的文本文件

标签 c sockets server-side serversocket

我想从客户端发送一个文本文件,并想在服务器端读取该文本文件,并希望在服务器终端屏幕上显示文本。我已经成功地为服务器和多个客户端编写了代码。我还从客户端向服务器端发送了一个文本文件。但现在我想知道如何修改文本文件并发送它并读取服务器端从客户端发送的文本文件。我的服务器和客户端代码一起给出如下:

服务器和客户端代码:

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdint.h>
#include <stdlib.h>
#include <pthread.h>
#define filename "//home//myname//Documents//folder1//folder2//input.txt"

#define MAX_CLIENTS 5


//the thread function
void *new_connection_handler(void *);

int main(int argc , char *argv[])
{

    //client variables
    int sock;
    struct sockaddr_in server;
    char buffer[256], server_reply[2000];
    int len;

    //server variables
    int socket_desc , client_sock;
    struct sockaddr_in client;
    socklen_t c = sizeof(client);


    //check if the the command contain less than two arguments
    if(argc != 2)
    {
        printf("use either: %s <server/client>\n", argv[0]);
    }

    // If the command contains minumum 2 arguments
    else{


        // If argv is client then execute the client code
        if(strcmp("client",argv[1]) == 0)
        {
            /****************/// Client code here **********************************************************************
            //Create socket
            sock = socket(AF_INET , SOCK_STREAM , 0);
            if (sock == -1)
            {
                printf("Could not create socket");
            }
            puts("Socket created");

            server.sin_addr.s_addr = inet_addr("127.0.0.1");
            server.sin_family = AF_INET;
            server.sin_port = htons( 8888 );


            //Connect to remote server
            if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0)
            {
                perror("connect failed. Error");
                return 1;
            }

            puts("Connected\n");


            //keep communicating with server
            /* Time to send the file */

            /******************************************************/
            FILE *pf;
            int fsize;

            pf = fopen(filename, "rb");
            if (pf == NULL)
            {
                printf("File not found!\n");
                return 1;
            }
            else
            {
                printf("Found file %s\n", filename);

                fseek(pf, 0, SEEK_END);
                fsize = ftell(pf);
                rewind(pf);

                printf("File contains %ld bytes!\n", fsize);
                printf("Sending the file now\n");
            }

            while (1)
            {
                // Read data into buffer.  We may not have enough to fill up buffer, so we
                // store how many bytes were actually read in bytes_read.
                int bytes_read = fread(buffer, sizeof(buffer), 1, pf);
                if (bytes_read == 0) // We're done reading from the file
                    break;

                if (bytes_read < 0)
                {
                    error("ERROR reading from file\n");
                }

                while (bytes_read > 0)
                {
                    int bytes_written = write(sock, buffer, bytes_read);
                    if (bytes_written <= 0)
                    {
                        error("ERROR writing to socket\n");
                    }

                }
            }

            printf("Done Sending the File!\n");
            printf("Now Closing Connection.\n");

            /*********************************************************************************/

            close(sock);

        }

        /****************/// Server code here **********************************************************************
        // If argv is server then execute the server code
        if(strcmp("server", argv[1]) == 0 )
        {
            //Create socket
            socket_desc = socket(AF_INET , SOCK_STREAM , 0);
            if (socket_desc == -1)
            {
                printf("Could not create socket");
            }

            //Prepare the sockaddr_in structure
            server.sin_family = AF_INET;
            server.sin_addr.s_addr = INADDR_ANY;
            server.sin_port = htons( 8888 );
            bzero (&server.sin_zero, 8);

            //Bind
            if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
            {
                //print the error message
                perror("bind failed. Error");
                return 1;
            }

            //Listen
            listen(socket_desc , MAX_CLIENTS);

            //Accept and incoming connection
            printf("Waiting for incoming connections\n");

            c = sizeof(client);
            while( (client_sock = accept(socket_desc, (struct sockaddr *)&client, &c)) )
            {
                printf("Connection accepted\n");
                pthread_t thread_id;

                if( pthread_create( &thread_id , NULL ,  new_connection_handler , (void*) (intptr_t)client_sock) < 0)
                {
                    perror("could not create thread");
                    return 1;
                }

                printf("Handler assigned\n");
            }


            if (client_sock < 0)
            {
                perror("accept failed");
                return 1;
            }
        } 
    }
    return 0;
}


void *new_connection_handler(void *socket_desc)
{
    //Get the socket descriptor
    int sock = (intptr_t)socket_desc;
    int read_size = 0;
    char client_message[2000];

    //PROBLEM **read the text file sent from client side and display the text on screen**
    while( (read_size = recv(sock , client_message , sizeof(client_message) , 0)) > 0 )
    printf("Read Text: %.*s", read_size, client_message);

if(read_size == 0)
{
    printf("Client disconnected\n");
    fflush(stdout);
}
else if(read_size == -1)
{
    perror("recv failed");
}


    return 0;
}

最佳答案

您在代码中犯了一些错误。

int bytes_read = fread(buffer, sizeof(buffer), 1 ,pf);

这个语句是错误的,当你打印bytes_read值时,它打印1有一个结果。如果你把它传递给next,它会重复打印h。

使用下面的语句代替那个 fread:

int bytes_read = fread(buffer, 1, sizeof(buffer), pf);

该语句仅返回正确的读取值。

while (bytes_read > 0)
{
   int bytes_written = write(sock, buffer, bytes_read);
   if (bytes_written <= 0)
   {
        error("ERROR writing to socket\n");
   }
}

在这部分代码中,您的程序不断地将读取的内容写入套接字,因此服务器不间断地打印文本。

因此,请在 write() bytes_read=bytes_read-bytes_writing; 之后使用此语句,如果读取缓冲区已完全写入套接字,则会中断该语句。

还有一件事是,当您尝试使用 file 时,始终尝试使用 long 数据类型,因为与 long 相比,int 的范围较小。

更新:
输入 fread(buffer, 1, sizeof(buffer), pf); 并尝试一下。它会起作用的。

<小时/>

您可以使用 open() 或 fopen()。

fd=open("filename",O_RDWR);

fd - 返回打开文件的描述符。
O_RDWR - 用于打开文件进行读写,必须包含 fcntl.h。

fp=fopen("filename","r+");

fp - 文件指针。
rw - 打开文件以进行读取和写入。

文件内容:

Chandru
ttttt.

替换后:

Stackoverflowt.

这里的内容很大,所以内容被覆盖在另一行中。 为了避免这种情况,您需要将更改的内容写入另一个文件中。 在另一个文件中写入可以很容易地将文本附加到行尾。

关于c - 使用 C 在服务器端读取从客户端发送的文本文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24729445/

相关文章:

c - 在同一 while 循环中接受用户输入和传入连接

stream - Dart同时路由到多个客户端

notepad++ - 如何让Notepad++在我设置的服务器上运行PHP文件?

php - ffmpeg 的问题

ios - Swift Socket,监听传入的消息

node.js - 如何从heroku 上的NodeJS 应用程序中删除socket.io 轮询日志?

c - 如何在不丢失主要轮廓的情况下将字母的灰度图像转换为二进制图像?

C 数组赋值在越界时有效

c - 在 C 语言中,当我在另一个文件中声明一个不同数据类型的全局变量时,为什么没有出现错误?

c - 如果我只有设备缓冲区 (PCIe) 的物理地址,我该如何将此缓冲区映射到用户空间?