为啥这会重复打印换行符?
Posted
技术标签:
【中文标题】为啥这会重复打印换行符?【英文标题】:Why does this repeatedly print newline?为什么这会重复打印换行符? 【发布时间】:2012-03-16 13:04:19 【问题描述】:来自 c 程序的套接字将 3 个数字发送到 python 中的套接字。下面的代码和输出:
python服务器代码:
import SocketServer
import threading
import select
import sys
class TCPHandler(SocketServer.StreamRequestHandler):
def handle(self):
self.data = self.rfile.readline()
print "%s wrote:" % self.client_address[0]
print (self.data)
self.request.send(str(long(self.data)+1000))
cur_connex.append('ip': self.client_address, 'range': [long(self.data), long(self.data)+10000])
for a in cur_connex:
print("%s did %d - %d on thread %s" % (a['ip'], a['range'][0], a['range'][1], threading.current_thread().name))
while True:
select.select([self.rfile], [], [])
self.data = self.request.recv(10) #also tried "self.data = self.rfile.readline().strip("\n")" and without "strip()"
print self.data
if __name__ == "__main__":
HOST, PORT = "", 50001
cur_connex = []
done_up_to = 0
# Create the server, binding to localhost on port 50001
server = SocketServer.TCPServer((HOST, PORT), TCPHandler)
# Activate the server on new thread
listen_thread = threading.Thread(target=server.serve_forever, name='listen_th')
listen_thread.start()
c++ 客户端代码:
for(unsigned long long i; i < perfect_numbers.size(); i++)
cout << "i is " << i << " writing " << perfect_numbers[i] << "\n";
for(int j = 0; j < perfect_numbers[i].size(); j++)
cout << perfect_numbers[i][j] << "|";
if(write(sock, perfect_numbers[i].c_str(), sizeof(perfect_numbers[i].c_str())) == -1)
cerr << "\nwrite failed: " << strerror(errno) << "\n";
return -1;
if(close(sock) == -1)
cerr << "close sock error: " << strerror(errno) << "\n";
return -1;
cout << "exiting...\n";
return 1;
服务器输出:
>>> 127.0.0.1 wrote:
12695
('127.0.0.1', 55624) did 12695 - 22695 on thread listen_th
28
496
8128
...然后是连续的换行符
客户端输出:
that took 1.26624 seconds
i is 0 writing 28
2|8|
|i is 1 writing 496
4|9|6|
|i is 2 writing 8128
8|1|2|8|
|exiting...
我认为 C++ 客户端程序的最后一点就足够了。还假设它在服务器中的 while True
循环中。对这两种语言都是新手,我知道我的编码还不够好,请温柔一点...
【问题讨论】:
【参考方案1】:这篇文章处理的内容比 OP 所要求的要多,我为这件事道歉。如果您只对如何修复在服务器上编写的待处理换行符感兴趣,请跳转到“python”部分。
客户端/服务器端
您应该在发送/接收的号码之间添加一个分隔符,不能保证每个号码都会单独到达。您可能会在同一次拨打self.request.recv (...)
时收到两个号码。
蟒蛇
print
将在传递给它的每个语句后附加一个换行符 ('\n'
),除非您以逗号结束 print
语句。
您应该添加一个检查,看看是否真的有任何数据要读取,如果没有,则可能出现错误或连接已关闭。
while True:
select.select([self.rfile], [], [self.rfile])
self.data = self.request.recv(10)
if self.data:
print self.data
else:
# <close connection here>
c++
write(sock, perfect_numbers[i].c_str(), sizeof(perfect_numbers[i].c_str()))
无论perfect_numbers[i]
的长度是1 字节还是10 亿字节,上面都会尝试将sizeof(char*)
字符写入套接字sock
。
write
的第三个参数应该是您希望写入的字节数,因此您应该使用perfect_numbers[i].size ()
。 1
1我假设您在查看以下示例时感到困惑:
char buf[1024];
...
write (sock, buf, sizeof (buf));
【讨论】:
我认为如果没有可读取的内容,recv() 会被阻止?我还认为选择被阻止,直到有东西要读? @FrederickCraine 如果连接已关闭或容易出错,则有“东西”要读取,但没有数据 - 只是一个必须修复的错误。你是对的,select.select
确实会阻塞,直到有东西要读取,但如果你发送数据的速度比处理它的速度快,你最终会在正在读取的缓冲区中得到多个“块”。【参考方案2】:
查看输出
i 是 0 写 28
2|8*| |*我 ...
我假设 perfect_numbers[i] 以 \n 结尾(在本例中为“28\n”)。列表是如何生成的?
【讨论】:
【参考方案3】:对于流请求处理程序,self.request
是一个 socket
对象。 socket.recv
函数在套接字关闭时返回一个空字符串。
【讨论】:
以上是关于为啥这会重复打印换行符?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我从 textarea 中提取换行符的方法是使用 \r [重复]