php 发送循环大数据

2013-11-12 06:06:06 e_wsq 阅读数 9732
  • Linux系统目录及必备命令学习

    通过本课程的学习,大家可以从懵懂到熟悉,从熟悉到熟练,能够在企业中熟练运用,同时在学习的过程中有任何不明白的地方,都可以向我咨询,我会积极帮助大家解决问题。

    217人学习 吴光科
    免费试看
关于socket大数据收发
现在遇到个问题,我们这边是做客户端的。服务器端是socket,不是我们写的,看不到源码,走的是tcp协议。我们的socket客户端在接收大数据(大约大于5000个byte)的时候总是不能一次性的接收所有的数据,一般是分2次。可能是1000,4000;2000,3000;4000,1000这样不固定的。但有个奇怪的现象,在debug的时候,数据是能一次收完整的。后来发现只要在xx。read(buffer)之前sleep几秒,数据就全了。现在不明白为什么会这样,以及怎么解决。听说tcp协议会保证数据包的顺序和完整性吗?现在数据的顺序是对的,但不完整。因为开发机是不能上网的,所以我贴不了代码。客户端用的是nio,写法我看了下是网上很常见的那种。

------解决方案--------------------
其实你这并不是问题,只是你疑惑而已,当你清楚Socket的工作原理后,你就不会疑惑了。
Socket里的inputStream和outputStream是负责Socket的输入和输出,并且他们都是阻塞的,除非关闭Socket或者shutdown对应的Stream。
为什么你sleep几秒后数据就全了呢?因为数据在Socket上是边传边收,而不是传完了再收,这是你理解的一个误区,所以我建议你们在传输数据的时候,能在头几位(这里是指byte)指明后面要接受的数据的长度,用read(buf,offset,len)方法肯定可以完整得到你想要的数据,不需要sleep(如果数据够大的话,sleep也是解决不了问题的)。或者你可以用一组约定字符表示结束,一直读到约定字符为止。 
------解决方案--------------------
TCP包的大小是有限制的,网络端口的缓存也有大小。
所以,如果你用普通SOCKET读数据,如果所续数据未收到,肯定会阻塞。 
------解决方案--------------------
最好修改下服务端。
就像楼上们说的,传输的数据有个一标志位,标志传输数据的总长度。这样在服务端接收时去判断这个标志位,如是收到了指定长度的时间则停止接收,如果长度不够,则循环接收,直到全部接收为止。 
------解决方案--------------------
探讨

数据发送是有时间的,而且一般是分批发送,所以一次性收不全很正常,循环收直到完整收下来就行了。


------解决方案--------------------
顺便问下,如果服务器端连续发送aaa和bbb两段报文。那接收方会不会收到bababa?
——绝对不会,但是可能会收到 3 组报文: aa ab bb

如果用长度来控制读取的长度,是不是要发送2次
——这是比较靠谱的做法
2018-11-10 04:25:40 hhduyc 阅读数 1684
  • Linux系统目录及必备命令学习

    通过本课程的学习,大家可以从懵懂到熟悉,从熟悉到熟练,能够在企业中熟练运用,同时在学习的过程中有任何不明白的地方,都可以向我咨询,我会积极帮助大家解决问题。

    217人学习 吴光科
    免费试看

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

问:socket异步接收数据? 1、客户端发送给服务器的字节长度大于服务器接收默认的字节长度的话,服务器会...
       答:客户端接收缓冲区设置多大就接收多大的数据包,当然发送端发送数据大于客户端缓冲区时,接收函数完成一次接收后会返回当前数据大小,你可以根据返回的做循环...

问:C#socket循环接收 socket接收数据如果对方没有返回 Recv。方法回阻塞线程而且会卡死,如果等待时间...
       答:应该要用事件来写吧,backgroundwork

问:socket编程中的接收数据丢失问题 这个是服务器的代码:#define MAX_BUFLEN 1024*256 main(int ac,char*av[]){ int...
       答:TCP协议通信,接收接收数据的前后次序与发送方一致,但数据包不一定一致。打个比方,发送方按顺序发送了2个数据包,接收可能仅接收1次就能全部收到,也可能...

问:socket编程服务器端接收数据 服务器端接收到一个socket就创建一个线程,recv()接收数据后保存,我是没接收...
       答:服务端:using System.;using System..Sockets;using System.Text;using System.Threading;Thread mythread;Socket socket;清理所有正在使用的资源。...

问:c里的socket能否检查是否有数据接收? 能的话怎么做?
       答:可以。select这个函数,就是用来做这个工作的。分接收和发送两种。编程例子,可查看参考资料。

问:asp. 用socket接收数据 知道IP,知道对方端口号,需要通过socket 用TCP方式发送一组数据到对方电脑并...
       答:client int port=8080;string host=\"192.168.1.206;IPAddress ip=IPAddress.Parse(host);IPEndPoint ipe=new IPEndPoint(ip,port);把ip和端口转化为IPEndPoint...

问:java的socket数据接收问题 服务端发送的是“00 3C 60 00 00 00 06 02 10 30 38 00 00 0E 80”,我写的接收...
       答:你这貌似打印的都是他的十六进制的十进制形式啊

问:boost:asio同一次连接中SOCKET能不能既接收数据又发送数据?... 
       答:1.建议使用一个socket专门接收数据,一个socket专门负责发送数据。2.如果使用一个socket既发送又接收,很可能出现这样的问题(如果该socket正在接收数据,而又想...

问:java中socket通讯如何实现服务器到服务器的数据传送和接收。爱... 最近在做一个项目,请问如何能够利用sockt通讯实现服务器之间的报文发送和接收?...
       答:当然,java的网络通信功能非常强大 Socket ServerSocket都是java提供的基础类 提醒你注意:(1)链接的超时限制(2)要使用多线程进行通信控制,否则同时只能有一个...

问:MFC socket编程 
       答:程序开启的时候创建SOCKET,绑定一个固定的端口,并开启一个线程并在其中循环的recvfrom创建的SOCKET上的数据,这样对方要发数据的时候就发送接收方的那个固定...

问:在socket应用通信中,如何用vb. 实现自动接收字符?爱问... 在socket应用通信中,如何用vb. 实现自动接收字符?重要的是自动接收,可以用...
       答:可以用timer 也可以用while循环来接受 至于为什么只能发英文 我想是你的编码没搞好 在发送前 调用 System.Text.Encoding.GetEncoding("utf-8")接受的时候也调用...

问:关于Socket关闭的一些细节 例如:在C/S形式中,关闭Socket时Server会接收到哪些消息?及其它一些细节。
       答:对于无连接的(UDP)socket任何时候数据接收都处于正常状态,只不过没有数据。对于连接的(TCP)socket 关闭时C/S任何一端都可以按照这样顺序执行:#ifdef WIN32#...

问:关于c# socket发送文件问题 我用c# socket异步发送文件,代码如下:do {socket.beginsend();这里报错 done....
       答:C#.网络程序开发(Socket)Microsoft. Framework为应用程序访问Inter提供了分层的、可扩展的以及受管辖的网络服务,其名字空间System.和System....

问:关于Grails的Socket传输对象与接收对象 我是一个Grails新手,想问下各位大虾,在Grails的socket编程中,如何传输对象,...
       答:应该是对的

问:java连接oracle数据库java.sql.SQLException:无效的列索引问题... java.sql.SQLException:无效的列索引 无效的列索引 at oracle.jdbc.driver....
       答:你的这部分代码大体上没有错误,但是你有几个常识应该注意:(1)数据库访问时,为了确保数据库系统安全,千万不要直接使用oracle的system、sysman、sys等用户...

问:TCP数据包是什么啊? 
       答:传输控制协议(Transmission Control Protocol,TCP)TCP协议主为了在主机间实现高可靠性的包交换传输协议。本文将描述协议标准和实现的一些方法。因为计算机网络...


           

给我老师的人工智能教程打call!http://blog.csdn.net/jiangjunshow

这里写图片描述
2012-07-29 22:28:45 chenjie3392593 阅读数 2251
  • Linux系统目录及必备命令学习

    通过本课程的学习,大家可以从懵懂到熟悉,从熟悉到熟练,能够在企业中熟练运用,同时在学习的过程中有任何不明白的地方,都可以向我咨询,我会积极帮助大家解决问题。

    217人学习 吴光科
    免费试看

PHP:PHP 5.3.6 (cli) (built: Jun 15 2011 16:29:50)

  MYSQL:5.1.51

  如果我们有的一张表有几百万或几千万的记录,我们要使用 PHP 将所有的记录都获取过来(遍历数据表)进行处理。查询语句:

  SELECT * FROM largetable;

  PS:为了证明上面的做法是最佳的办法,我尝试使用 largetable 中的一个字段做 where ,以及 LIMIT,OFFSET 。上面那种 WHERE 获得结果很慢,虽然用了索引。后面这种 LIMIT 可以让你有一种想死的感觉(有兴趣可以了解下,《分页优化》)。

  以 MYSQL 以及PDO_MYSQL 为例,尝试直接使用以下代码,必然会出现超内存的情况:

  $result = mysql_query($sql);

  while ($rowset = mysql_fetch_assoc($mysql)) {

  ...

  $stmt = $dbh->prepare($sql);

  $stmt->execute();

  while ($row = $stmt->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_NEXT)) {

  ...

  原因在于在查询执行后,PHP 的MYSQL、PDO_MYSQL 将查询结果全部缓存到了客户端,也就是 PHP 执行所在机器上。这样如果我们要 SELECT * FROM LARGETABLE 查询的记录在 百万以上的时候 ,缓存的结果就会非常大,超出 PHP 使用内存。所以为了避免这样情况就需要关闭客户端的缓存。

  这里提供二个测试脚本,分别为 MYSQL、PDO_MYSQL 关闭缓存后查询样例。点击下载:mysql_query

  以下是 PDO_MYSQL 在查询 ~100W 以及 ~200W (540M)数据结果(因为我的 PHP 内存使用设置了1G所以没挂:) )

  可以很明显的看出在缓存结果后占用内存惊人…,当我们处理千万数据的时候必挂。

\

  以下是 PDO_MYSQL 关闭缓存查询 ~200W 的数据结果。这下处理千万以及E级的数据的时候,对内存表示很淡定。

\

  PS:如果你要处理的数据就几十万,你还是调大点内存好了。比如 MYSQL:

  mysql_unbuffered_query() 的好处是有代价的:在 mysql_unbuffered_query() 返回的结果集之上不能使用 mysql_num_rows() 和 mysql_data_seek()。此外在向 MySQL 发送一条新的 SQL 查询之前,必须提取掉所有未缓存的 SQL 查询所产生的结果行。

2013-10-16 02:20:04 e_wsq 阅读数 7254
  • Linux系统目录及必备命令学习

    通过本课程的学习,大家可以从懵懂到熟悉,从熟悉到熟练,能够在企业中熟练运用,同时在学习的过程中有任何不明白的地方,都可以向我咨询,我会积极帮助大家解决问题。

    217人学习 吴光科
    免费试看

问:socket异步接收数据? 1、客户端发送给服务器的字节长度大于服务器接收默认的字节长度的话,服务器会...
       答:客户端接收缓冲区设置多大就接收多大的数据包,当然发送端发送数据大于客户端缓冲区时,接收函数完成一次接收后会返回当前数据大小,你可以根据返回的做循环...

问:C#socket循环接收 socket接收数据如果对方没有返回 Recv。方法回阻塞线程而且会卡死,如果等待时间...
       答:应该要用事件来写吧,backgroundwork

问:socket编程中的接收数据丢失问题 这个是服务器的代码:#define MAX_BUFLEN 1024*256 main(int ac,char*av[]){ int...
       答:TCP协议通信,接收接收数据的前后次序与发送方一致,但数据包不一定一致。打个比方,发送方按顺序发送了2个数据包,接收可能仅接收1次就能全部收到,也可能...

问:socket编程服务器端接收数据 服务器端接收到一个socket就创建一个线程,recv()接收数据后保存,我是没接收...
       答:服务端:using System.;using System..Sockets;using System.Text;using System.Threading;Thread mythread;Socket socket;清理所有正在使用的资源。...

问:c里的socket能否检查是否有数据接收? 能的话怎么做?
       答:可以。select这个函数,就是用来做这个工作的。分接收和发送两种。编程例子,可查看参考资料。

问:asp. 用socket接收数据 知道IP,知道对方端口号,需要通过socket 用TCP方式发送一组数据到对方电脑并...
       答:client int port=8080;string host=\"192.168.1.206;IPAddress ip=IPAddress.Parse(host);IPEndPoint ipe=new IPEndPoint(ip,port);把ip和端口转化为IPEndPoint...

问:java的socket数据接收问题 服务端发送的是“00 3C 60 00 00 00 06 02 10 30 38 00 00 0E 80”,我写的接收...
       答:你这貌似打印的都是他的十六进制的十进制形式啊

问:boost:asio同一次连接中SOCKET能不能既接收数据又发送数据?... 
       答:1.建议使用一个socket专门接收数据,一个socket专门负责发送数据。2.如果使用一个socket既发送又接收,很可能出现这样的问题(如果该socket正在接收数据,而又想...

问:java中socket通讯如何实现服务器到服务器的数据传送和接收。爱... 最近在做一个项目,请问如何能够利用sockt通讯实现服务器之间的报文发送和接收?...
       答:当然,java的网络通信功能非常强大 Socket ServerSocket都是java提供的基础类 提醒你注意:(1)链接的超时限制(2)要使用多线程进行通信控制,否则同时只能有一个...

问:MFC socket编程 
       答:程序开启的时候创建SOCKET,绑定一个固定的端口,并开启一个线程并在其中循环的recvfrom创建的SOCKET上的数据,这样对方要发数据的时候就发送接收方的那个固定...

问:在socket应用通信中,如何用vb. 实现自动接收字符?爱问... 在socket应用通信中,如何用vb. 实现自动接收字符?重要的是自动接收,可以用...
       答:可以用timer 也可以用while循环来接受 至于为什么只能发英文 我想是你的编码没搞好 在发送前 调用 System.Text.Encoding.GetEncoding("utf-8")接受的时候也调用...

问:关于Socket关闭的一些细节 例如:在C/S形式中,关闭Socket时Server会接收到哪些消息?及其它一些细节。
       答:对于无连接的(UDP)socket任何时候数据接收都处于正常状态,只不过没有数据。对于连接的(TCP)socket 关闭时C/S任何一端都可以按照这样顺序执行:#ifdef WIN32#...

问:关于c# socket发送文件问题 我用c# socket异步发送文件,代码如下:do {socket.beginsend();这里报错 done....
       答:C#.网络程序开发(Socket)Microsoft. Framework为应用程序访问Inter提供了分层的、可扩展的以及受管辖的网络服务,其名字空间System.和System....

问:关于Grails的Socket传输对象与接收对象 我是一个Grails新手,想问下各位大虾,在Grails的socket编程中,如何传输对象,...
       答:应该是对的

问:java连接oracle数据库java.sql.SQLException:无效的列索引问题... java.sql.SQLException:无效的列索引 无效的列索引 at oracle.jdbc.driver....
       答:你的这部分代码大体上没有错误,但是你有几个常识应该注意:(1)数据库访问时,为了确保数据库系统安全,千万不要直接使用oracle的system、sysman、sys等用户...

问:TCP数据包是什么啊? 
       答:传输控制协议(Transmission Control Protocol,TCP)TCP协议主为了在主机间实现高可靠性的包交换传输协议。本文将描述协议标准和实现的一些方法。因为计算机网络...


2017-06-23 14:30:19 wyljz 阅读数 6491
  • Linux系统目录及必备命令学习

    通过本课程的学习,大家可以从懵懂到熟悉,从熟悉到熟练,能够在企业中熟练运用,同时在学习的过程中有任何不明白的地方,都可以向我咨询,我会积极帮助大家解决问题。

    217人学习 吴光科
    免费试看

服务器端代码:

 public void SendTextMsg(string str)
        {
            int maxlength = 1000;
            int page = 0;
            if (str.Length % maxlength == 0)
            {
                page = str.Length / maxlength;
            }
            else
            {
                page = str.Length / maxlength + 1;
            }
            for (int i = 0; i < page; i++)
            {
                string tmp = null;
                if (i < page - 1)
                {
                    tmp = str.Substring(i * maxlength, maxlength);
                }
                else
                {
                    tmp = str.Substring(i * maxlength);
                }
                var jobj = new
                {
                    total = page,
                    index = i,
                    data = tmp
                };
                string jstr = Newtonsoft.Json.JsonConvert.SerializeObject(jobj);
                string bstr = Common.ToBase64(jstr);//编码转换,起到加密和防止汉字乱码的作用
                //System.Diagnostics.Debug.WriteLine("{0} {1}", jstr.Length, jstr);
                base.Send(bstr+"#end#");
            }
        }

客户端代码:

try
            {
                chksocket();
                string jstr = getpara(msg, cmd);
                string mm = string.Format("LOGA {0}\r\n", jstr);
                byte[] buffer = Encoding.UTF8.GetBytes(mm);
                _socket.Send(buffer);
                Dictionary<int, string> data = new Dictionary<int, string>();
                string tmpData = "";
                while (true)
                {
                    buffer = new byte[1];
                    int rev = _socket.Receive(buffer);
                    string result = Encoding.UTF8.GetString(buffer);
                    tmpData += result;
                    if (tmpData.EndsWith("#end#"))
                    {
                        //编码转换,起到加密和防止汉字乱码的作用
                        string jstr = Common.FromBase64(tmpData.Replace("#end#", ""));
                        JObject jobj = JObject.Parse(jstr);
                        int index = int.Parse(jobj["index"].ToString());
                        string ds = jobj["data"].ToString();
                        int total = int.Parse(jobj["total"].ToString());
                        data.Add(index, ds);
                        tmpData = "";
                        if (data.Count == total)
                        {
                            break;
                        }
                    }
                }
                Dictionary<int, string> dic = data.OrderBy(p => p.Key).ToDictionary(p => p.Key, o => o.Value);
                StringBuilder sb = new StringBuilder();
                foreach (KeyValuePair<int, string> item in dic)
                {
                    sb.Append(item.Value);
                }
                return sb.ToString();
            }
            catch (Exception e)
            {
                throw e;
            }