TCP传输中的奇怪行为

时间:2013-04-18 16:04:46

标签: java c sockets

我的服务器 - 客户端应用程序包含以下模块:

客户端(用Java编写)连接到服务器并发送文件;

server(用C编写)接收文件并发送char数组消息。

问题是收到文件后,服​​务器无法发送邮件或客户端无法接收邮件。

这是我的服务器应用程序代码:

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, bytesRead;
    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
    printf("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;
    }

    printf("Connection accepted");

    //Receive image
    while((bytesRead = recv(new_socket, buffer, buffer_len, 0)) > 0)
    {
        fwrite(buffer, 1, bytesRead, f);
    }

    fclose(f);
    printf("\nReceive finished!");


    //Send messsage
    char my_message[100];
    strcpy(my_message, "Hello World!");

    send(new_socket, my_message, strlen(my_message), 0);

    closesocket(s);
    WSACleanup();

    getch();
    return 0;
}

客户端应用程序的代码:

public class MyClass
{
    public static void main(String[] args) 
    {
        String fileName = "1.jpg", receiveMessage;
        File a_file = new File(fileName);  
        int j;
        OutputStream output = null;
        InputStream input = null;
        ObjectInputStream in = null;
        Socket socket = null;

        try  
        {           
            // Create a socket
            socket = new Socket("192.168.0.122", 8888);

            FileInputStream fileInputStream = new FileInputStream(fileName);
            byte[] buffer = new byte[1000];
            int bytesRead = 0;
            output = socket.getOutputStream();     
            input = socket.getInputStream();     

            while((bytesRead = fileInputStream.read(buffer))>0)
            {
                output.write(buffer,0,bytesRead);
            }

            fileInputStream.close();        
            System.out.println("Send finished!");

            input.read(buffer);
            System.out.println("Receive finished!");
        }  
        catch(Exception e)  
        {  
            e.printStackTrace();  
        } 
        finally
        {
            try
            {
                in.close();
                output.close();
                socket.close();
            }
            catch(Exception e)
            {

            }
        }
    }
}

有什么想法可以解决这个问题吗?提前谢谢!

1 个答案:

答案 0 :(得分:3)

这是因为你有阻塞套接字。创建套接字(通过连接或接受)时,它处于阻塞模式。这意味着如果没有要接收的数据,它将不会返回,从而有效地阻止了调用者。

因此,在收到服务器循环中的最后一个字节后,recv调用将无限期阻止。

在带有winsockets的Windows上,使用ioctlsocket函数进行套接字阻塞或非阻塞。链接引用有一个示例,显示热插拔阻塞或非阻塞。