简体   繁体   English

对等方重置连接:套接字写入错误C ++-Java

[英]Connection reset by peer: socket write error c++ - java

I am trying to write a server-client application for file transfer. 我正在尝试编写用于文件传输的服务器-客户端应用程序。 The client is written in Java and the server is written in C++. 客户端用Java编写,服务器用C ++编写。

Unfortunately I have the following error: 不幸的是我有以下错误:

java.net.SocketException: Connection reset by peer: socket write error" java.net.SocketException:连接被同级重置:套接字写入错误”

Here is my code for client: 这是我给客户的代码:

 import java.io.*;
 import java.net.Socket;


 public class Proba_binar 
 {
     public static void main(String[] args) 
     {
         byte[] buffer = null;  
         byte[] auxByte = new byte[1000];  
         String fileName = "1.jpg";
         File a_file = new File(fileName);  
         try  
         {
             // Create a socket
             Socket socket = new Socket("192.168.14.146", 8888);

             BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

             BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));


             // Read file
             FileInputStream fis = new FileInputStream(fileName);    
             int length = (int)a_file.length();  
             buffer = new byte[length];  
             fis.read(buffer);  
             fis.close();  

             // Send file length
             System.out.println("length = " + Integer.toString(length));
             out.write(Integer.toString(length) + "\n");
             out.flush();

             // Send file
             int imageSize = buffer.length;
             char[] auxChar = new char[1000];
             int nr_transf = imageSize / 1000;
             int rest_byte = imageSize % 1000;
             System.out.println("nr_transf = " + nr_transf);

             for(int j = 0; j < nr_transf; j++)
             {
                 // send series of 1000 bytes
                 for(int i = 0; i < 1000; i++)
                 {
                     auxChar[i] = (char)buffer[j*1000+i];
                     auxByte[i] = buffer[j*1000+i];
                 }
                 out.write(auxChar);
                 out.flush();
             }

             // send last bytes
             for(int i = 0; i < rest_byte; i++)
             {
                 auxChar[i] = (char)buffer[1000*nr_transf+i];
                 auxByte[i] = buffer[1000*nr_transf+i];
             }
             out.write(auxChar, 0, rest_byte);
             out.flush();

             out.close();
            in.close();
            socket.close();
            System.out.println("Transfer finished!");
         }  
         catch(IOException e)  
         {  
             e.printStackTrace();  
         } 
     }
 }

And the code for server: 和服务器的代码:

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

 {

     WSADATA wsa;

     SOCKET s , new_socket;

     struct sockaddr_in server , client;

     int c, bytecount, nr_transf, rest_byte, i;

     int recv_size, file_size;

     char message[1000];

    char buffer[1000];
    int buffer_len = 1000;
    FILE *f = fopen("out.jpg", "wb");

     printf("\nInitialising Winsock...");
     if (WSAStartup(MAKEWORD(2, 2),&wsa) != 0)
     {
         printf("Failed. Error Code : %d",WSAGetLastError());
         return 1;
    }

     printf("Initialised.\n");

     //Create a socket
     if((s = socket(AF_INET, SOCK_STREAM, 0 )) == INVALID_SOCKET)
     {
         printf("Could not create socket : %d" , WSAGetLastError());
        getch();
        return 0;
     }

     printf("Socket created.\n");

     //Prepare the sockaddr_in structure
     server.sin_family = AF_INET;
     server.sin_addr.s_addr = INADDR_ANY;
     server.sin_port = htons( 8888 );

     //Bind
     if(bind(s, (struct sockaddr*)&server, sizeof(server)) == SOCKET_ERROR)
     {
         printf("Bind failed with error code : %d" , WSAGetLastError());
        getch();
        return 0;
     }

     puts("Bind done");

     //Listen to incoming connections
     listen(s, 3);

     //Accept and incoming connection
     puts("Waiting for incoming connections...");

     c = sizeof(struct sockaddr_in);
     new_socket = accept(s, (struct sockaddr*)&client, &c);
     if (new_socket == INVALID_SOCKET)
     {
         printf("accept failed with error code : %d", WSAGetLastError());
        getch();
        return 0;
     }

     puts("Connection accepted");

     //Receive FILE DIMENSION from client

     if((recv_size = recv(new_socket, message, 1000, 0)) == SOCKET_ERROR)
     {
         puts("recv failed");
        getch();
     }     
        message[recv_size] = '\0';
    file_size = atoi(message);

    printf("\nfile_size = %d", file_size);

    nr_transf = file_size / 1000;
    rest_byte = file_size % 1000;

    //Receive FILE from client

    for(i = 0; i < nr_transf; i++)

    {

        // receive 1000 bytes

        if((bytecount = recv(new_socket, buffer, buffer_len, 0)) == SOCKET_ERROR)   

        {

            printf("Receive failed auxChar");

            getch();

            return 0;

        }

        fwrite(buffer, 1, buffer_len, f);

    }

    // receive last bytes

    if((bytecount = recv(new_socket, buffer, rest_byte, 0)) == SOCKET_ERROR)    

    {

        printf("Receive failed rest_byte");

        getch();

        return 0;

    }

    fwrite(buffer, 1, rest_byte, f);

    fclose(f);

    printf("Receive finished!");





     closesocket(s);

     WSACleanup();



    getch();

     return 0;

 }

I made equivalent server in Java and works perfectly. 我用Java制造了等效的服务器,并且运行良好。 I do not know what the problem is in c + + version. 我不知道c ++版本中存在什么问题。 Thanks in advance! 提前致谢!

recv() does not guarantee that it will read all bytes requested: recv()不保证它将读取所有请求的字节:

...calling recv will return as much data as is currently available—up to the size of the buffer specified... ...调用recv将返回当前可用的尽可能多的数据-达到指定缓冲区的大小...

This means that the for / recv loop is incorrectly structured and it is probably the case that the server believes it has read all the data but it has not. 这意味着for / recv循环的结构不正确,很可能是服务器认为自己已读取所有数据但尚未读取所有数据。 This results in the server closing the socket before the client has sent all the data, resulting in the error reported by the Java client. 这导致服务器在客户端发送所有数据之前关闭套接字,从而导致Java客户端报告错误。

Example (untested) restructuring of the recv loop: recv循环的示例(未经测试)重组:

int totalBytesRead = 0;
int bytesRead;
while (totalBytesRead < file_size)
{
    if((bytesRead = recv(new_socket, buffer, buffer_len, 0)) == SOCKET_ERROR)
    {
        /* Handle failure. */
        break;
    }

    if (bytesRead != fwrite(buffer, 1, bytesRead, f))
    {
        /* Handle failure. */
        break;
    }

    totalBytesRead += file_size;
}

Remember that connected sockets are stream based, using mutilple send() s does not imply that the matching recv() s will read the data in the same "chunks" as they were sent. 请记住,连接的套接字基于流,使用mutilple send()并不意味着匹配的recv()会读取与发送时相同的“块”中的数据。 In addition to the data content retrieval error already mentioned, this equally applies to the reading of the file size. 除了已经提到的数据内容检索错误外,这同样适用于读取文件大小。 There is no guarantee that entire file size will be read. 无法保证将读取整个文件的大小。

I would recommend designing a simple protocol to ensure the different types of data are correctly read. 我建议设计一个简单的协议,以确保正确读取不同类型的数据。 For example, client sends: 例如,客户端发送:

<file_size>\\n<file_content> <文件大小> \\ n <文件内容>

the server reads all data up to the newline character and converts it into the file size. 服务器读取所有数据,直到换行符为止,并将其转换为文件大小。 The server then knows for certain it has the correct file size. 然后,服务器肯定会知道它具有正确的文件大小。 The server then reads file_size bytes from the socket. 然后,服务器从套接字读取file_size字节。 Finally, server responds to indicate success or failure: 最后,服务器响应以指示成功或失败:

success\\n 成功\\ n

the client reads up to the newline character to obtain the response. 客户端读取换行符以获取响应。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Java - 对等方重置连接:套接字写入错误 - Java - Connection reset by peer: socket write error 对等方重置连接:Java 中的套接字写入错误,用于文件传输程序 - Connection reset by peer: socket write error in java for file transfer program java异常:对等连接重置:套接字写入错误 - java Exception: connection reset by peer: socket write error 对等方重置连接:套接字写入错误 docker - Connection reset by peer: socket write error docker 对等方重置HttpClient连接:套接字写入错误 - HttpClient Connection reset by peer: socket write error JTDS - java.sql.SQLException:I / O错误:通过对等方重置连接:套接字写入错误 - JTDS - java.sql.SQLException: I/O Error: Connection reset by peer: socket write error ClientAbortException:java.net.SocketException:由peer重置连接:套接字写入错误 - ClientAbortException: java.net.SocketException: Connection reset by peer: socket write error java.net.SocketException: Connection reset by peer: socket write error 提供文件时 - java.net.SocketException: Connection reset by peer: socket write error When serving a file “ java.net.SocketException:对等体重置连接:套接字写入错误”我该如何解决 - “java.net.SocketException: Connection reset by peer: socket write error” How can I solve it 对等方重置连接:套接字写入错误。 我的Java代码有什么问题 - Connection reset by peer: socket write error. What is wrong with my Java code
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM