2014-03-03 211 views
0

我有我的連接工作和數據傳輸工作......在某種程度上。我正在設計一個設置客戶端和服務器套接字的小程序。一旦連接,客戶端就可以發送文件到服務器。Perl套接字文件傳輸問題

我的問題是,當我開始發送我的「測試」文件時,服務器永遠不會結束它的while循環。它將數據連接到輸出文件中。更奇怪的是,輸出文件中的數據是正確的,除了行之間有額外的空白。

我知道這是因爲我沒有咀嚼\ n字符,而是在服務器上添加了另一個\ n字符。但是,如果我在客戶身上嘮叨,那麼一切都在一條線上。因此,服務器(不管它是否添加換行符)都將其輸出到一行,因爲它只收到一行。如果我在服務器端chomp,我得到一個空的文本文件......這讓我感到困惑。

此外,服務器從不停止連接......即使在客戶端斷開連接後,它也會造成無限循環。終端輸出這種無限期:

Use of uninitialized value $data in concatenation (.) or string at ./tcp_server.pl line 51, <GEN2> line 14. 

這裏是我的服務器代碼:

#!/usr/bin/perl 

# Flushing to STDOUT after each write 
$| = 1; 

use warnings; 
use strict; 
use IO::Socket::INET; 
use v5.10; 

# Server side information 
my $listen_port = '7070'; 
my $protocal  = 'tcp'; 

# Finds IP address of host machine 
# Connects to example site on HTTP 
my $ip_finder = IO::Socket::INET->new(
    PeerAddr=> "www.google.com", 
    PeerPort=> 80, 
    Proto => "tcp" 
) or die "The IP can not be resolved: $!\n"; 

# The found IP address of Host 
my $ip_address = $ip_finder->sockhost; 

# Creating socket for server 
my $server = IO::Socket::INET->new (
    LocalPort => $listen_port, 
    Proto  => $protocal, 
    Listen  => 5, 
    Reuse  => 1, 
) or die "Socket could not be created, failed with error: $!\n"; # Prints error code 
print "Socket created using IP: $ip_address\n"; 
print "Waiting for client connection on port $listen_port\n"; 

# Accept connection 
my $client_socket = $server->accept(); 

open(my $fh, ">out") 
    or die "File can not be opened: $!"; 
while($client_socket) { 

    # Retrieve client information 
    my $client_address = $client_socket->peerhost(); 
    my $client_port = $client_socket->peerport(); 
    print "Client accepted: $client_address, $client_port\n"; 

    my $data = <$client_socket>; 
    print $fh "$data\n"; 

} 
close $fh; 
$server->close(); 

和客戶端:

#!/usr/bin/perl 

# Flushing to STDOUT after each write 
$| = 1; 

use warnings; 
use strict; 
use IO::Socket::INET; 
use v5.10; 

# Client side information 
# Works by setting $dest to server address, needs to be on same domain 
# my $dest  = '<IP goes here>'; 
# my $dest  = '<IP goes here>'; 
my $dest  = '<host>.cselabs.umn.edu'; 
my $port  = '7070'; 
my $protocal = 'tcp'; 

my $client = IO::Socket::INET->new (
    PeerHost => $dest, 
    PeerPort => $port, 
    Proto  => $protocol, 
) or die "Socket could not be created, failed with error: $!\n"; # Prints error code 

print "TCP connection established!\n"; 

open(my $fh, "<test") 
    or die "Can't open: $!"; 
while(my $line = <$fh>) { 
    print $client $line; 
} 
close $fh; 
# sleep(10); 
$client->close(); 
+0

這是不是一個好主意,揭示您正在使用的機器的IP地址,特別是當開發一個完全不關心安全的協議! – salva

+0

我明白了,這有些不同。這個範圍非常小。這是一個家庭作業,我只是有點麻煩。通過顯示IP,我可以將它輸入到我的客戶端。這對我在不同的主機上運行時很好。它只是讓我更容易。我完全理解這個問題! – rusty

+0

我的意思是,任何人讀這個線程將能夠訪問您的服務器和濫用其錯誤來控制機器。 – salva

回答

1

你不會在客戶端中添加新行。客戶端只是從文件(包括換行符)中讀取一行並將其打印到套接字,但不會添加另一個換行符。但是在服務器上,您從套接字(包括換行符)中讀取該行並添加另一個換行符。另外,服務器中的循環條件不正確。你不應該檢查套接字是否存在,因爲即使在連接關閉之後它仍然存在。相反,您應該在閱讀時檢查錯誤(這是您未定義警告的來源)。而且,最好不要一行一行地閱讀,而應該獨立於行,例如塊。

while (read($client_socket, my $data, 8192)) { 
    print $fh $data; 
} 
+0

我會記住這個!我可能會在我的UDP版本中實現這個答案。我想通了,並沒有使用相同的while循環進行文件傳輸了。他們仍然是相似的,可能會更好...但我設法來回傳送一些圖片文件,它正在工作。謝謝! – rusty