免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1648 | 回复: 4
打印 上一主题 下一主题

python socket编程的一些疑问,求教高手解答 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-02-06 11:42 |只看该作者 |倒序浏览
最近需要写一个服务器端的程序,客户端是用C写的,并且不清楚客户端是怎么操作的,而在写服务器端程序出现了以下的问题:
1.客户端上报的数据,经常出现有时候能上报,但大多数时候都不能上报的情况,这是怎么造成的?是不是自己写的服务器程序将数据阻塞住了,需要在服务器端设置一个buffer?这个buffer又应该怎么设置?
2.客户端的数据是一条一条的报文,特点是每条报文结束后都有一个$作为结束符,我想在每条报文前加上日期时间等前缀信息,再一起写入文件,如果仅仅是使用recv,就可能出现只上报了日期,而报文却被截断没有上报的情况,该怎么解决?是不是可以使用唯一字符串结束标示符,这个东西应该怎么用呢?


好像问的问题比较傻比较乱,还烦请大神们帮忙解答,这个程序是我在网络基础编程上的一个例子修改了一下得来的
————————————————————————————————————————————————————————————————————————————
import socket
import traceback
import time
import os
import os.path

dir=os.getcwd()
fname='report.txt'
file=os.path.join(dir,fname)
f=open(file,'a')


host = ''                               # Bind to all interfaces
port = 10000

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host, port))
s.listen(5)

while True:
    try:
        clientsock, clientaddr = s.accept()
    except KeyboardInterrupt:
        raise
    except:
        traceback.print_exc()
        continue

    # Process the connection

    try:        
        while True:
            curtime=time.strftime('%Y-%m-%d,%H:%M:%S',time.localtime())
            client=str(clientsock.getpeername())
            data = clientsock.recv(4096)
            report=' '.join((curtime,client,data))

            if data!='':
                f.write(report+'\n')
            if not len(data):
                break
    except (KeyboardInterrupt, SystemExit):
        raise
    except:
        traceback.print_exc()

    # Close the connection

    try:
        clientsock.close()
    except KeyboardInterrupt:
        raise
    except:
        traceback.print_exc()

f.close()

论坛徽章:
0
2 [报告]
发表于 2013-02-06 18:18 |只看该作者
本帖最后由 darkn3ss 于 2013-02-06 18:19 编辑

你应该去看看最基本的tcp编程,python跟c语言的tcp编程在处理流程上是基本一致的。
你的recv流程是有问题的,每次只接受4096个字节,tcp是流式传输,也就是说传输流有可能是连续的,4096的强制截取会将一个完整的流截断,剩下的数据将会随着连接断开而被抛弃,以下是较为正确的代码:

  1. def tcp_recv(self, fileno):
  2.         data = ''
  3.         while True:
  4.             try:
  5.                 delta = self.data_sock_pool[fileno].recv(self.tcp_recv_buff_size)
  6.                 if not delta:
  7.                     break
  8.                 data = '%s%s'%(data, delta)
  9.             except IOError, e:
  10.                 if e.args[0] == errno.EWOULDBLOCK:
  11.                     break
  12.         if not data:
  13.             self.close_conn(fileno, 'data_sock_pool')
  14.             return False
  15.         else:
  16.             self.in_buffer[fileno] = '%s%s'%(self.in_buffer[fileno], data)
  17.             self.break_buffer_to_message(fileno)
  18.             return True
复制代码
这是用epoll库nonblock模式下编写的,可能跟你使用的同步模式有点差异,总而言之,就是需要一次完整接受完整个tcp流数据
如果想使用数据报的话,建议用udp模式

论坛徽章:
0
3 [报告]
发表于 2013-02-07 10:50 |只看该作者
对于socket编程是个完全的初学者,你给的这个对于我来说还太高深了,不过不知道这个epoll在windows下能不能用?

论坛徽章:
0
4 [报告]
发表于 2013-02-07 10:50 |只看该作者
回复 2# darkn3ss
对于socket编程是个完全的初学者,你给的这个对于我来说还太高深了,不过不知道这个epoll在windows下能不能用?

   

论坛徽章:
0
5 [报告]
发表于 2013-02-07 16:48 |只看该作者
回复 4# young_py


win下的tcp编程参考这个吧,简单的
http://blog.csdn.net/trbbadboy/article/details/7408003
  1. if((clientsoc = accept(serversoc, (SOCKADDR *)&clientaddr, &len))<=0)  
  2.     {  
  3.         printf("Accept fail!\n");  
  4.         return -1;  
  5.     }  
  6.     printf("Connected\n");  
  7.     while(1)  
  8.     {  
  9.         //waiting for data receive  
  10.         if(recv(clientsoc, buf, BUFLEN, 0) <= 0)   
  11.         {  
  12.             //some error occur  
  13.             printf("Close connection\n");  
  14.             closesocket(clientsoc);  
  15.             break;  
  16.         }  
  17.         printf("%s\n",buf);  
  18.     }  
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP