gpt4 book ai didi

macos - 使用 Swift 的套接字服务器示例

转载 作者:IT王子 更新时间:2023-10-29 05:31:50 26 4
gpt4 key购买 nike

我试着做了一个简单的套接字服务器的例子。

构建并运行成功。但是效果不佳。

客户端无法连接到此服务器。

如何解决这个问题?我需要你的帮助,谢谢。

import Foundation

let BUFF_SIZE = 1024

func initStruct<S>() -> S {
let struct_pointer = UnsafePointer<S>.alloc(1)
let struct_memory = struct_pointer.memory
struct_pointer.destroy()
return struct_memory
}

func sockaddr_cast(p: ConstUnsafePointer<sockaddr_in>) -> UnsafePointer<sockaddr> {
return UnsafePointer<sockaddr>(p)
}

func socklen_t_cast(p: UnsafePointer<Int>) -> UnsafePointer<socklen_t> {
return UnsafePointer<socklen_t>(p)
}

var server_socket: Int32
var client_socket: Int32
var server_addr_size: Int
var client_addr_size: Int

var server_addr: sockaddr_in = initStruct()
var client_addr: sockaddr_in = initStruct()

var buff_rcv: Array<CChar> = []
var buff_snd: String

server_socket = socket(PF_INET, SOCK_STREAM, 0);

if server_socket == -1
{
println("[Fail] Create Server Socket")
exit(1)
}
else
{
println("[Success] Created Server Socket")
}

server_addr_size = sizeof(server_addr.dynamicType)
memset(&server_addr, 0, UInt(server_addr_size));

server_addr.sin_family = sa_family_t(AF_INET)
server_addr.sin_port = 4000
server_addr.sin_addr.s_addr = UInt32(0x00000000) // INADDR_ANY = (u_int32_t)0x00000000 ----- <netinet/in.h>

let bind_server = bind(server_socket, sockaddr_cast(&server_addr), socklen_t(server_addr_size))

if bind_server == -1
{
println("[Fail] Bind Port");
exit(1);
}
else
{
println("[Success] Binded Port");
}

if listen(server_socket, 5) == -1
{
println("[Fail] Listen");
exit(1);
}
else
{
println("[Success] Listening : \(server_addr.sin_port) Port ...");
}

var n = 0

while n < 1
{
client_addr_size = sizeof(client_addr.dynamicType)
client_socket = accept(server_socket, sockaddr_cast(&client_addr), socklen_t_cast(&client_addr_size))

if client_socket == -1
{
println("[Fail] Accept Client Connection");
exit(1);
}
else
{
println("[Success] Accepted Client : \(inet_ntoa(client_addr.sin_addr)) : \(client_addr.sin_port)");
}

read(client_socket, &buff_rcv, UInt(BUFF_SIZE))

println("[Success] Received : \(buff_rcv)")

buff_snd = "\(strlen(buff_rcv)) : \(buff_rcv)"

write(client_socket, &buff_snd, strlen(buff_snd) + 1)

close(client_socket)
}

最佳答案

socket地址中的端口号必须是big-endian字节序:

server_addr.sin_port = UInt16(4000).bigEndian

所以你的程序实际上监听端口 40975(十六进制 0xA00F)而不是在端口 4000(十六进制 0x0FA0)上。

另一个问题是:

var buff_rcv: Array<CChar> = []
// ...
read(client_socket, &buff_rcv, UInt(BUFF_SIZE))

您的缓冲区是一个 数组,但recv() 需要一个大小为BUFF_SIZE 的缓冲区。行为未定义。要获得所需大小的缓冲区,请使用

var buff_rcv = [CChar](count:BUFF_SIZE, repeatedValue:0)
// ...
read(client_socket, &buff_rcv, UInt(buff_rcv.count))

备注:这里您将 Int 的地址转换为 socklen_t 的地址并将其传递给 accept() 函数:

client_socket = accept(server_socket, sockaddr_cast(&client_addr), socklen_t_cast(&client_addr_size))

那是不安全的。如果 Intsocklen_t 有不同的大小那么行为将是未定义的。您应该声明 server_addr_sizeclient_addr_size作为 socklen_t 并移除 socklen_t_cast() 函数:

client_socket = accept(server_socket, sockaddr_cast(&client_addr), &client_addr_size)

关于macos - 使用 Swift 的套接字服务器示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24977805/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com