PHP/Go套接字通信

huangapple go评论90阅读模式
英文:

PHP/Go socket communication

问题

我正在尝试使用套接字在Go和PHP之间进行通信。我正在使用的代码如下:

Go:

fmt.Println("Launching server...")
ln, _ := net.Listen("tcp", ":8080")
conn, _ := ln.Accept()

for {
    message, _ := bufio.NewReader(conn).ReadString('\n')
    fmt.Print("Message Received:", string(message))
    conn.Write([]byte("test" + "\n"))
}

PHP:

$address = gethostbyaddr($ip);
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if($socket === false){
    echo "socket_create() failed: reason: " . socket_strerror(socket_last_error());
}

$result = socket_connect($socket, $address, $port);
if ($result === false) {
    echo "socket_connect() failed.\nReason: ($result) " . socket_strerror(socket_last_error($socket));
} 
socket_write($socket, "test", 4);
socket_read($socket, 4);

问题是Go服务器一直认为它在接收到某些内容,所以它不断地打印"Message Received:"。如果我使用if(message!=""),它似乎可以工作,但CPU使用率很高。

另一个问题是,除非我在PHP中注释掉socket_read($socket, 4);,否则服务器不会接收到"test"。

英文:

Im trying to communicate between Go and PHP with a socket. The code im using is:

Go:

fmt.Println("Launching server...")
ln, _ := net.Listen("tcp", ":8080")
conn, _ := ln.Accept()

for {
	message, _ := bufio.NewReader(conn).ReadString('\n')
	fmt.Print("Message Received:", string(message))
	conn.Write([]byte("test" +"\n"))
	
}

PHP:

$address = gethostbyaddr($ip);
	$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
	if($socket === false){
		echo "socket_create() failed: reason: " . socket_strerror(socket_last_error());
	}

	$result = socket_connect($socket, $address, $port);
	if ($result === false) {
	    echo "socket_connect() failed.\nReason: ($result) " . socket_strerror(socket_last_error($socket));
	} 
    socket_write($socket, "test", 4);
    socket_read($socket, 4);

The problem is that the Go server keeps thinking it's receiving something all the time so it prints "Message Recieved:" constantly. If i do if(message!="") it sort of works but the cpu usage is high.

Another problem is that the server doesn't receive "test" unless i comment out the socket_read($socket, 4); in PHP.

答案1

得分: 1

ReadString文档中提到:

> 如果在找到分隔符之前,ReadString遇到错误,它会返回错误之前读取的数据和错误本身(通常是io.EOF)。

这意味着你会得到io.EOF(表示连接中没有更多可读取的数据)和一个空字符串。

如果你希望在没有可用数据时阻塞ReadString,不要使用bufio,而是直接从连接中读取。

另请参阅:net.Conn文档

> 另一个问题是,除非我在PHP中注释掉socket_read($socket, 4);,否则服务器不会接收到“test”。

这在这里有描述,socket_write会进行缓冲:

> socket_write()不一定会将给定缓冲区中的所有字节都写入。[...]

在写入后使用

fflush($socket);

来刷新缓冲区。

英文:

The documentation for ReadString says:

> If ReadString encounters an error before finding a delimiter, it returns the data read before the error and the error itself (often io.EOF).

This means that you're getting io.EOF (indicating that there's no more data to be read from the connection) and an empty string.

If you want to block on ReadString when no data is available, don't use bufio but rather read directly from the connection.

See also: documentation for net.Conn

> Another problem is that the server doesn't receive "test" unless i comment out the socket_read($socket, 4); in PHP.

That's described here, socket_write buffers:

> socket_write() does not necessarily write all bytes from the given buffer. [...]

use

fflush($socket);

after the write.

huangapple
  • 本文由 发表于 2015年4月30日 17:01:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/29963401.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定