- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我正在尝试编写一个简单的客户端-服务器应用程序。它在同一台计算机上的双方都可以正常工作,但在两台不同的计算机上运行时会阻塞。这些计算机是 RaspBerry Pi 2 和 MacBook Pro。
问题是客户端在二进制中阻塞。在几次良好运行后写入。通常,接收数据的服务器打印它已收到 63,而发送数据的客户端打印它将发送 64。
如果我将截止日期通知服务器,它会超时退出。客户端也有截止日期但不会超时。
我尝试用简单的字节数组或单个 int 替换数据。它仍然阻塞。但数据越小,正确的次数就越多。
如果我删除客户端中的 Printf 函数,它也会运行更长的时间。
我还尝试通过从套接字到 STDIO 的简单副本来替换服务器的功能(我在某处找到的提示),但它仍然无法从 binary.Write 中出来。
有什么想法吗?
这是完整的源代码。那里有一些伪造的东西(例如计数循环),但它们真的很简单。还是我弄错了?
package main
import (
// "bytes"
"encoding/binary"
"fmt"
"io"
"net"
"os"
"os/exec"
"runtime/trace"
"time"
"unsafe"
)
type TheMessageType struct {
X int32
RestOfMessage [1000]byte
}
func listener(theCounter int, active bool, f *os.File) {
var message TheMessageType
var err error
var conn net.Conn
count := theCounter
for {
// Dial the server
fmt.Printf("LISTENER %d: connecting to socket\n", count)
conn, err = net.Dial("tcp", "192.168.1.113:49152")
if err != nil {
fmt.Printf("LISTENER %d: not connected, retrying in 3 seconds\n", count)
time.Sleep(3 * time.Second)
} else {
fmt.Printf("LISTENER %d: connected\n", count)
break
}
}
defer conn.Close()
// Loop writing to socket
for {
// Set deadline
// conn.SetDeadline(time.Now().Add(2 * time.Second))
// Print some info
fmt.Printf("LISTENER %d: writing from %v to %v\n", count, conn.LocalAddr(), conn.RemoteAddr())
// Prepare message to write to socket
message.X = int32(count)
theString := fmt.Sprintf("%d", count)
copy(message.RestOfMessage[:], theString)
// binary write directly to socket
fmt.Printf("LISTENER %d: binary.Write this: %d, %s\n", count, message.X, message.RestOfMessage)
f.Sync()
err = binary.Write(conn, binary.LittleEndian, message)
f.Sync()
fmt.Printf("LISTENER %d: written\n", count)
// time.Sleep(50 * time.Millisecond)
checkError(err, "LISTENER")
count = count + 1
}
}
func main() {
var myMessage TheMessageType
var ln net.Listener
var conn net.Conn
var err error
var theCount int
var avgspeed, speed float64
var speedlist [10]float64
curspeed := 0
const listenerActive = true
const mainActive = false
f, err := os.Create("theFile.out")
trace.Start(f)
t0 := time.Now()
t1 := time.Now()
transferSize := unsafe.Sizeof(myMessage)
fmt.Printf("MAIN: timestamp %s ; size of transfers is %d\n", t0.String(), transferSize)
if mainActive {
fmt.Println("MAIN: listen")
ln, err = net.Listen("tcp", ":49152")
fmt.Println("MAIN: defer")
defer ln.Close()
fmt.Println("MAIN: checkError")
checkError(err, "MAIN")
}
// launch listener
if listenerActive {
go listener(theCount, listenerActive, f)
}
for theCount = 1; ; theCount++ {
if mainActive {
fmt.Println("MAIN: accept")
conn, err = ln.Accept()
checkError(err, "MAIN")
exit := false
for !exit {
// Set deadline
// conn.SetDeadline(time.Now().Add(2 * time.Second))
// Print some info
fmt.Printf("MAIN: reading on %v from %v\n", conn.LocalAddr(), conn.RemoteAddr())
// move time
t0 = t1
// read from socket
fmt.Println("MAIN: reader")
f.Sync()
err = binary.Read(conn, binary.LittleEndian, &myMessage)
f.Sync()
if err == io.EOF {
fmt.Println("EOF!")
exit = true
conn.Close()
} else {
checkError(err, "MAIN")
}
// clear screen
c := exec.Command("clear")
c.Stdout = os.Stdout
c.Run()
// print received data
fmt.Printf("MAIN: socket message received: %d, %s\n", myMessage.X, myMessage.RestOfMessage)
// calculate speed & average
t1 = time.Now()
tdif := t1.Sub(t0)
speed = float64(transferSize) / tdif.Seconds() / 1000000.0 * 8.0
speedlist[curspeed] = speed
curspeed = curspeed + 1
if curspeed == 10 {
curspeed = 0
}
totalspeed := 0.0
for i := 0; i < 10; i++ {
totalspeed += speedlist[i]
}
avgspeed = totalspeed / 10
// print speed
fmt.Printf("MAIN: avg mbit/s %9.2f ; actual mbit/s: %9.2f\n", avgspeed, speed)
// time.Sleep(1 * time.Second)
}
}
}
}
func checkError(err error, name string) {
if err != nil {
fmt.Fprintf(os.Stderr, "%s: Fatal error: %s\n", name, err.Error())
// panic(fmt.Sprintf("%v", err.Error()))
os.Exit(1)
}
}
这是客户端被阻止写入时的堆栈跟踪:
goroutine 1 [running]:
runtime.throw(0x1927b8, 0x5)
/usr/local/go/src/runtime/panic.go:527 +0x90 fp=0xc82004bd78 sp=0xc82004bd60
runtime.sigpanic()
/usr/local/go/src/runtime/sigpanic_unix.go:27 +0x2ba fp=0xc82004bdc8 sp=0xc82004bd78
main.main()
/Users/ple/dev/go/src/Peter-test/main.go:108 +0x33c fp=0xc82004bf50 sp=0xc82004bdc8
runtime.main()
/usr/local/go/src/runtime/proc.go:111 +0x2b0 fp=0xc82004bfa0 sp=0xc82004bf50
runtime.goexit()
/usr/local/go/src/runtime/asm_amd64.s:1696 +0x1 fp=0xc82004bfa8 sp=0xc82004bfa0
goroutine 17 [syscall, locked to thread]:
runtime.goexit()
/usr/local/go/src/runtime/asm_amd64.s:1696 +0x1
goroutine 5 [trace reader (blocked)]:
runtime.ReadTrace(0x0, 0x0, 0x0)
/usr/local/go/src/runtime/trace.go:339 +0x207
runtime/trace.Start.func1(0x5a42e0, 0xc82002a020)
/usr/local/go/src/runtime/trace/trace.go:28 +0x18
created by runtime/trace.Start
/usr/local/go/src/runtime/trace/trace.go:34 +0x78
goroutine 6 [runnable]:
reflect.Value.Index(0x1234c0, 0xc8204ac004, 0x51, 0x75, 0x12ac00, 0xc8204ac078, 0x48)
/usr/local/go/src/reflect/value.go:823
encoding/binary.(*encoder).value(0xc8200475a0, 0x1234c0, 0xc8204ac004, 0x51)
/usr/local/go/src/encoding/binary/binary.go:509 +0x808
encoding/binary.(*encoder).value(0xc8200475a0, 0x162ba0, 0xc8204ac000, 0x59)
/usr/local/go/src/encoding/binary/binary.go:518 +0xb4f
encoding/binary.Write(0x621138, 0xc8200a2000, 0x621160, 0x289ef0, 0x162ba0, 0xc8204ac000, 0x0, 0x0)
/usr/local/go/src/encoding/binary/binary.go:316 +0x1792
main.listener(0x0, 0x1, 0xc82002a020)
/Users/ple/dev/go/src/Peter-test/main.go:59 +0xac8
created by main.main
/Users/ple/dev/go/src/Peter-test/main.go:105 +0x332
最佳答案
吉姆的回答是正确的。 Main 进入忙循环。我通过将一个 channel 传递给监听器并在 main 的末尾等待它来解决它。客户端在 for 循环之后“写入”它,这是一个无限循环,所以 main 永远不会结束。从那时起,程序就一直在传递数据。为了确定,我会让它运行一整夜。
我只得到大约 12.5Mbit/s,这有点滑稽。连接是 1Gbit Wifi AC 到 100mbit 以太网交换机到 Raspberry Pi。但这是另一个问题。
谢谢!
关于sockets - binary.Write to socket in go blocks,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32370700/
基于 socket.io 的官方网站 http://socket.io/#how-to-use , 我找不到任何术语。socket.emit 、 socket.on 和 socket.send 之间有
我正在使用 lua-socket 3.0rc1.3(Ubuntu Trusty 附带)和 lua 5.1。我正在尝试监听 unix 域套接字,我能找到的唯一示例代码是 this -- send std
这两者有什么区别? 我注意到如果我在一个工作程序中从 socket.emit 更改为 socket.send ,服务器无法接收到消息,虽然我不明白为什么。 我还注意到,在我的程序中,如果我从 sock
使用套接字在两台服务器之间发送数据是个好主意,还是应该使用 MQ 之类的东西来移动数据。 我的问题:套接字是否可靠,如果我只需要一次/有保证的数据传输? 还有其他解决方案吗? 谢谢。 最佳答案 套接字
引自 this socket tutorial : Sockets come in two primary flavors. An active socket is connected to a
我已经安装了在端口81上运行的流服务器“Lighttpd”(light-tpd)。 我有一个C程序,它使用套接字api创建的服务器套接字在端口80上监听http请求。 我希望从客户端收到端口80上的请
这是我正在尝试做的事情: 当有新消息可用时,服务器会将消息发送给已连接的客户端。另一方面,客户端在连接时尝试使用send()向服务器发送消息,然后使用recv()接收消息,此后,客户端调用close(
如何将消息发送到动态 session 室,以及当服务器收到该消息时,如何将该消息发送到其他成员所在的同一个 session 室? table_id是房间,它将动态设置。 客户: var table_i
这是我尝试但不起作用的方法。我可以将传入的消息从WebSocket连接转发到NetSocket,但是只有NetSocket收到的第一个消息才到达WebSocket后面的客户端。 const WebSo
我正在实现使用boost将xml发送到客户端的服务器。我面临的问题是缓冲区不会立即发送并累积到一个点,然后发送整个内容。这在我的客户端造成了一个问题,当它解析xml时,它可能具有不完整的xml标记(不
尝试使用Nginx代理Gunicorn套接字。 /etc/systemd/system/gunicorn.service文件 [Unit] Description=gunicorn daemon Af
我正在使用Lua套接字和TCP制作像聊天客户端和服务器这样的IRC。我要弄清楚的主要事情是如何使客户端和服务器监听消息并同时发送它们。由于在服务器上执行socket:accept()时,它将暂停程序,
我看了一下ZMQ PUSH/PULL套接字,尽管我非常喜欢简单性(特别是与我现在正在通过UDP套接字在系统中实现的自定义碎片/ack相比),但我还是希望有自定义负载平衡功能,而不是幼稚的回合-robi
我正在编写一个应用程序,其中有多个 socket.io 自定义事件,并且所有工作正常,除了这个: socket.on("incomingImg", function(data) {
在我的应用程序中,我向服务器发送了两条小消息(类似 memcached 的服务)。在类似 Python 的伪代码中,这看起来像: sock.send("add some-key 0") ignored
很抱歉再次发布此问题,但大多数相关帖子都没有回答我的问题。我在使用 socket.io 的多个连接时遇到问题我没有使用“socket.socket.connect”方法,但我从第一次连接中得到了反馈。
我尝试使用 socket.io 客户端连接到非 socket.io websocket 服务器。但我做不到。我正在尝试像这样连接到套接字服务器: var socket = io.connect('ws
我遇到了一个奇怪的问题。在我非常基本的服务器中,我有: server.listen(8001); io.listen(server); var sockets = io.sockets; 不幸的是,套
我正在使用带套接字 io 的sailsjs。帆的版本是 0.10.5。我有以下套接字客户端进行测试: var socketIOClient = require('socket.io-client');
这个问题在这里已经有了答案: What is the fundamental difference between WebSockets and pure TCP? (4 个答案) 关闭 4 年前。
我是一名优秀的程序员,十分优秀!