2011-12-17 110 views
0

我一直在为此苦苦挣扎。我正在尝试创建一个应该在两个客户端之间单播消息的简单UDP服务器。客户端是一个iOS客户端(接收器)和一个Mac客户端(发送者)。如果我从mac发送一些东西,目前是一个字符串,它应该出现在iOS应用程序中,但现在情况并非如此。我认为(或希望),我已经找到了问题的服务器,它目前是这样的:具有多个客户端的Ruby UDP服务器?

require 'socket' 
@host = "0.0.0.0" 
@port = 80 
BasicSocket.do_not_reverse_lookup = true 
# Create socket and bind to address 
socket = UDPSocket.new 
socket.setsockopt(Socket::SOL_SOCKET,Socket::SO_BROADCAST, 1) 
socket.bind(@host, @port) 
while true do 
    data, addr = socket.recvfrom(1024) # if this number is too low it will drop the larger packets and never give them to you 
    puts [addr[0], data] 
    socket.send(data, 0, @host, addr[1]) 
    puts "Sender address: #{addr[1]}" 
end 

在我使用AsyncUdpSocket客户端,相关部分看起来是这样的:

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    socket = [[AsyncUdpSocket alloc] initWithDelegate:self]; 
    [socket bindToPort:80 error:nil]; 
    [socket enableBroadcast:YES error:nil]; 
    [self sendMessage:@"Sent from my iPhone"]; 
    [socket receiveWithTimeout:-1 tag:0]; 
} 

- (void)sendMessage:(NSString *)message 
{   
    NSData *data = [[NSData alloc] initWithData:[message dataUsingEncoding:NSUTF8StringEncoding]]; 
    [socket sendData:data toHost:@"0.0.0.0" port:80 withTimeout:-1 tag:0]; 
} 

- (BOOL)onUdpSocket:(AsyncUdpSocket *)sock didReceiveData:(NSData *)data withTag:(long)tag fromHost:(NSString *)host port:(UInt16)port 
{ 
    NSString *theLine=[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; //Convert the UDP data to an NSString 
    NSLog(@"%@", theLine); 
    status.text = theLine; 
    [socket receiveWithTimeout:-1 tag:0]; 

    return YES; 
} 

当我运行在Mac和iOS客户端我从服务器得到以下结果:

enter image description here

即两个不同的地址,现在,当我发送S来自iOS设备(或模拟器)的东西,它会将它发送给服务器以回应它,但是只发送给发件人,而不是其他客户端,因为它们似乎有两个不同的端口/地址。那么,我该如何创建一个将消息发送给多个客户端的服务器呢?

更新现在我正在尝试使用线程向新线程添加新客户端。但是现在我遇到了相反的问题,所有的客户端都得到相同的端口。我的新的服务器看起来是这样的:

require 'socket' 
@host = "0.0.0.0" 
@port = 80 
BasicSocket.do_not_reverse_lookup = true 
# Create socket and bind to address 
socket = UDPSocket.new 
socket.setsockopt(Socket::SOL_SOCKET,Socket::SO_BROADCAST, 1) 
socket.bind(@host, @port) 
clients = [] 

def broadcast(data, clients)     
    clients.each do |client| 
    puts client[1] 
    puts data 
    socket.send(data, 0, "#{client[0]}", client[1]) 
    end 
end 

while true 
    data, client = socket.recvfrom(1024) 
    Thread.new(client) do |client| 
    puts "New client has joined" 
    clients << client 
    begin 
     loop do 
     broadcast(data, clients) 
     end 
    rescue EOFError         
     client.close 
     clients.delete(client)        
     puts "client left" 
    end 
    end 
end 

输出:关于如何解决这一问题

enter image description here

技巧将是惊人的!

回答

1

终于得到它的工作(我认为),工作服务器看起来是这样的:

require 'socket' 
@host = "0.0.0.0" 
@port = 80 
BasicSocket.do_not_reverse_lookup = true 
# Create socket and bind to address 
@socket = UDPSocket.new 
@socket.setsockopt(Socket::SOL_SOCKET,Socket::SO_BROADCAST, 1) 
@socket.bind(@host, @port) 
@clientPorts = [] 

def broadcast(data, clients)     
    puts clients 
    clients.each do |client| 
    @socket.send(data, 0, @host, client) 
    end 
end 

while true 
    data, client = @socket.recvfrom(1024) 
    Thread.new(client) do |clientAddress| 
    puts "New client has joined" 
    unless @clientPorts.include? clientAddress[1] 
     @clientPorts << clientAddress[1] 
    end 
    broadcast(data, @clientPorts) 
    end 
end