精华内容
下载资源
问答
  • python socket.recv() 一直不停的返回空字符串原因。 我遇到的是,因为客户端异常断开连接,之后服务端就一直接收到空字符串。 这样会无法分辨是客户端真的了一个空串还是怎么样。 下面是复现问题的demo。 先...

    python socket.recv() 一直不停的返回空字符串原因。

    我遇到的是,因为客户端异常断开连接,之后服务端就一直接收到空字符串。

    这样会无法分辨是客户端真的发了一个空串还是怎么样。

    下面是复现问题的demo。

    先运行server端:

    # coding=utf-8
    import socket
    if __name__ == '__main__':
        host = 'localhost'
        port = 8765
    
        server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        server.bind((host, port))
        server.listen(1)  # 连接数
        client, address = server.accept()
        while True:  # 循环收发数据包
            data = client.recv(1024)
            print ("data:"+data)
    
    

    再运行client端:

    # coding=utf-8
    import socket
    import time
    
    if __name__ == '__main__':
        host = 'localhost'
        port = 8765
        client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        client.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)  # 在客户端开启心跳维护
    
        while True:
            client.connect((host, port))  # ###注意这里,会报错导致代码崩溃,这时候去看服务端输出,就可以看到无限就收空串
            client.send('hello world\r\n'.encode())
            print('send data')
    

    最终运行结果:

    客户端结果:
    
    
    send data
    Traceback (most recent call last):
      File "C:/Users/Rorschach/Desktop/test/test2.py", line 17, in <module>
        client.connect((host, port))  # ###注意这里,会报错导致代码崩溃,这时候去看服务端输出,就可以看到无限就收空串
      File "C:\Python27\Lib\socket.py", line 228, in meth
        return getattr(self._sock,name)(*args)
    socket.error: [Errno 10056] A connect request was made on an already connected socket
    
    
    服务端结果:
    
    
    C:\Users\Rorschach\PycharmProjects\untitled\venv\Scripts\python.exe C:/Users/Rorschach/Desktop/test/test1.py
    data:hello world
    
    hello world
    
    data:
    
    data:
    
    data:
    
    data:
    
    data:
    
    data:
    
    data:
    
    data:
    
    data:
    
    data:
    
    data:
    
    data:
    
    data:
    
    data:
    
    data:
    
    data:
    
    data:
    
    data:
    
    data:
    
    data:
    
    data:
    
    data:
    
    data:
    
    data:
    
    data:
    
    data:
    
    data:
    
    data:
    
    data:
    
    data:
    
    data:
    
    data:
    
    data:
    
    data:
    
    data:
    
    data:

    参考:https://blog.csdn.net/bbg221/article/details/78464051

    侵删

    展开全文
  • 我最开始是这样构想的,如果客户端发送88的消息,那么直接关闭服务器端的消息,但是阴差阳错,C#客户端的代码写错了,就看到了这个现象,那就是如果客户端socket代码关闭的话,服务器端会一直接收到消息 ...

    我最开始是这样构想的,如果客户端发送88的消息,那么直接关闭服务器端的消息,但是阴差阳错,C#客户端的代码写错了,就看到了这个现象,那就是如果客户端socket代码关闭的话,服务器端会一直接收到空消息
    最初的代码是这样的:
    python服务端

    # coding=utf-8
    # 使用utf-8编码
    # coding=utf-8
    # 使用utf-8编码
    import socket
    import select
    
    # the max player number
    playerNumber = 10
    
    # host and port
    host = socket.gethostname()
    port = 12345
    
    # create socket named mySocket,based on TCP
    mySocket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    
    # bind
    mySocket.bind(("127.0.0.1",port))
    
    # listen
    mySocket.listen(playerNumber)
    
    # 不能设为空,因为select会报错
    Socket_List = [mySocket]
    
    while True:
        # select 监听请求对象,如果没有收到请求,则阻塞,此处相当于监听accept事件
        # myEvent为响应事件对象,这里返回的就是socket,若响应的是accept事件,则返回本身的服务器socket,若响应recv,则返回客户端socket
        myEvent,wret,xret = select.select(Socket_List,[],[])
        print myEvent
        for i in myEvent:
            if i is mySocket:
                conn,addr = i.accept()
                Socket_List.append(conn)
            else:
                # 接收到消息,输出
                try:
                    receiveData = i.recv(1024)
                    print(receiveData)
                    # 铭记,客户端正常关闭的话
                    # 这里直接判断接收的是否为空字符串即可
                    if receiveData == "88":
                        Socket_List.remove(i)
                        i.close()
                        continue
                # 客户端关闭了,从sockelist中删除
                except:
                    Socket_List.remove(i)
                    i.close()
                    continue
    mySocket.close()
    

    C#客户端 注意看一里面if的判断的注释

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace TCP客户端
    {
        class Program
        {
            static void Main(string[] args)
            {
    
    
                //创建socket
                Socket mySocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //链接
                mySocket.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 12345));
    
                while (true)
                {
                    //发送一条消息
                    string sendData = Console.ReadLine();
                    //看这里看这里!!!
                    //我写错了,没发送消息呢,就直接关闭了
                    //那么服务端肯定接受不到啊
                    //然后就一直接受空消息
                    //把if这段代码放到mySocket.Send的下面就行了
                    if (sendData == "88")
                    {
                        mySocket.Close();
                        break;
                    }
                    mySocket.Send(Encoding.UTF8.GetBytes(sendData));
                }
                mySocket.Close();
            }
    
    
    
        }
    }
    
    
    展开全文
  • python socket.recv() 一直不停的返回空字符串,客户端怎么判断连接被断开?

    之前写代码的时候, 发现socket的 recv 函数一直返回空字符串。 

    感觉很是奇怪,自己没有去设置阻塞模式,也就是默认的阻塞模式,为什么不阻塞在那里,而是要一直收到空呢?

    去python的官网上仔细查看了这个函数的说明,托 防火长城 的福,等了半天,终于打开了这个美国的网站。

    socket. recv ( bufsize [flags ] )

    Receive data from the socket. The return value is a string representing the data received. The maximum amount of data to be received at once is specified by bufsize. See the Unix manual page recv(2) for the meaning of the optional argument flags; it defaults to zero.

    Note

     

    For best match with hardware and network realities, the value of bufsize should be a relatively small power of 2, for example, 4096.

    就这么短短的一段话,并没有说明重复收到空字符串是咋回事。 因为服务端是别人写的,我一直不得解释。 后面我自己写了个服务端,不小心把服务端代码写错,半途崩溃了,客户端又出现了这样的问题。 

    经过测试,发现通道断开或者close之后,就会一直收到空字符串。 而不是所谓的-1 或者报异常。这个跟C 和java等其他语言很不一样

    我后续仔细浏览了整个socket文档,一直没有发现通道断开后会出现的情况。 老外的文档其实写的也不是那么仔细。至少这个点没有写。 


    百度了许久没有找到这个答案,于是我自己写出来,希望可以给迷茫在这个点上的孩子一点光亮。


    如有其他问题,可以留言。

    展开全文
  • 用ServerSocket接收客户端消息,并返回给客户端,客户端是用C写的,数据的传输是16进制的数据,中间会涉及到字符串的拼接,就会遇到一些坑 字节数组的理解 数据传输必定要以IO流方式传输,并且是以二进制字节流方式,...

    用ServerSocket接收客户端消息,并返回给客户端,客户端是用C写的,数据的传输是16进制的数据,中间会涉及到字符串的拼接,就会遇到一些坑

    字节数组的理解

    数据传输必定要以IO流方式传输,并且是以二进制字节流方式,传输前要把要传输的数据转成字节数组,同样的数据,通过不同方式得到的字节数组结果不同(在计底层都是"111111001111111"的二进制),如图:
    在这里插入图片描述
    Java中,getBytes()方法的得到的字节数组,数组内元素是对每个字符当作一个ASCII字符转成对于的十进制
    HexConvertUtil.hexStringToBytes(str),是把两个字符当作一个16进制字符对应的十进制 ,比如 7E–>126 7F–>127 这正是设备之间传输需要的字节数组,

    16进制数据转字节数组的坑(切记勿用小写)

    16进制是不区分大小写的,但是在拼接返回数据时,小写会导致返回的数据不正确,当时我在用StringBuffer拼接数据,被拼接的数据,转为字节数组,字节数组里的元素为-1,并不是想要的结果,如图:

    小写:
    在这里插入图片描述
    大写:
    在这里插入图片描述

    可能会需要的工具类

    
        /**
         * Created by Administrator on 2019/1/5.
         */
        public class HexConvertUtil {
        
            /**
             * 在进制表示中的字符集合
             */
            final static char[] digits = {'0', '1', '2', '3', '4', '5', '6', '7', '8',
                    '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
                    'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y',
                    'Z'};
        
        //    /**
        //     * 字符串转为16进制数据
        //     *
        //     * @param str
        //     * @return
        //     */
        //    public static String convertStringToHex(String str) {
        //
        //        char[] chars = str.toCharArray();
        //
        //        StringBuffer hex = new StringBuffer();
        //        for (int i = 0; i < chars.length; i++) {
        //            hex.append(Integer.toHexString((int) chars[i]));
        //        }
        //
        //        return hex.toString();
        //    }
        
            /**
             * 16进制转为字符串
             * @param hex
             * @return
             */
            public static String convertHexToString(String hex) {
        
                StringBuilder sb = new StringBuilder();
                StringBuilder sb2 = new StringBuilder();
        
                for (int i = 0; i < hex.length() - 1; i += 2) {
        
                    String s = hex.substring(i, (i + 2));
                    int decimal = Integer.parseInt(s, 16);
                    sb.append((char) decimal);
                    sb2.append(decimal);
                }
        
                return sb.toString();
            }
        
            /**
             * 16进制字符串到字节数组
             * @param hexString
             * @return
             */
            public static byte[] hexStringToBytes(String hexString) {
                if (hexString == null || hexString.equals("")) {
                    return null;
                }
                String replace = hexString.replace(" ", "");
                // toUpperCase将字符串中的所有字符转换为大写
                hexString = replace.toUpperCase();
                int length = replace.length() / 2;
                // toCharArray将此字符串转换为一个新的字符数组。
                char[] hexChars = replace.toCharArray();
                byte[] d = new byte[length];
                for (int i = 0; i < length; i++) {
                    int pos = i * 2;
                    d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
                }
                return d;
            }
        
            /**
             * 返回匹配字符
             * @param c
             * @return
             */
            private static byte charToByte(char c) {
        
                return (byte) "0123456789ABCDEF".indexOf(c);
            }
        
            /**
             * 将字节数组转换为short类型,即统计字符串长度
             * @param b
             * @return
             */
            public static short bytes2Short2(byte[] b) {
                short i = (short) (((b[1] & 0xff) << 8) | b[0] & 0xff);
                return i;
            }
        
            /**
             * 将字节数组转换为16进制字符串
             * @param bytes 字节数组
             * @return
             */
            public static String BinaryToHexString(byte[] bytes) {
                String hexStr = "0123456789ABCDEF";
                String result = "";
                String hex = "";
                for (byte b : bytes) {
                    hex = String.valueOf(hexStr.charAt((b & 0xF0) >> 4));
                    hex += String.valueOf(hexStr.charAt(b & 0x0F));
                    result += hex + " ";
                }
                return result;
            }
        
            /**
             * 将其它进制的数字(字符串形式)转换为十进制的数字
             * @param str1  其它进制的数字(字符串形式)
             * @param base 传进的字符串原始进制数
             * @return
             */
            public static long toDecimalism(String str1, int base) {
                //去除空格
                String str = str1.replace(" ", "");
                char[] buf = new char[str.length()];
                str.getChars(0, str.length(), buf, 0);
                long num = 0;
                for (int i = 0; i < buf.length; i++) {
                    for (int j = 0; j < digits.length; j++) {
                        if (digits[j] == buf[i]) {
                            num += j * Math.pow(base, buf.length - i - 1);
                            break;
                        }
                    }
                }
                return num;
            }
        
            /**
             * 将十进制的数字转换为指定进制的字符串
             *
             * @param n    十进制的数字
             * @param base 指定的进制
             * @return
             */
            public static String toOtherBaseString(long n, int base) {
                long num = 0;
                if (n < 0) {
                    num = ((long) 2 * 0x7fffffff) + n + 2;
                } else {
                    num = n;
                }
                char[] buf = new char[32];
                int charPos = 32;
                while ((num / base) > 0) {
                    buf[--charPos] = digits[(int) (num % base)];
                    num /= base;
                }
                buf[--charPos] = digits[(int) (num % base)];
                return new String(buf, charPos, (32 - charPos));
            }
    
    

    如有理解错误的地方,请与我交流,共同学习,共同进步

    展开全文
  • socket传输结构体,c++,发送OK,recv返回字节大小正确但接受数据为 服务端在ubuntu服务器下,客户端在windows下,采用socket进行通信,在客户端接收数据时,出现了诡异的情况,recv返回值大于0,但缓冲区大小...
  • Socket 中 常见的返回错误解析

    千次阅读 2012-05-19 23:48:16
    下面列出了几个在客户与服务进程连接中常见的几个 Socket 错误,并分析了原因。后续再逐渐补充吧。 ECONNABORTED 该错误被描述为“software caused connection abort”,即“软件引起的连接中止”。原因在于当服务...
  • 今天学习了java 的网络编程中的 Socket , 就自已写了一个客户端 Socket 和一个服务端 ServerSocket, 测试时发现, 服务端接收到了客户端发送过来的数据, 而客户端没有接收到服务端返回的消息, 下面给出问题代码 ...
  • Java-----Socket中read方法什么时候返回-1
  • 在使用socket获取输入流读取数据时,总是提示指针。获取输入流getInputstream()和创建socket是在一个线程中执行,又创建一个线程处理输入流中的数据。然后就会报错。 public class ReceiveThread implements ...
  • socket写了消息客户端和服务器,在android studio的模拟器中运行的很正常,可一到手机上 就完全链接不上,为什么到手机上就不正常了呢?代码没有问题,在模拟器上很正常, 可以连接上也可以发送消息,一到手机上...
  • 一、背景 系统:CentOS7 64位 物理机 IP:192.168.2.199/24 使用端口:9999 ...服务端正常监听,但是客户端在连接时却连接不上,connect()函数返回-1。 服务端部分代码 int main(int argc, ch...
  • ![图片说明](https://img-ask.csdn.net/upload/201512/31/1451533534_472252.png)
  • 基于Socket网络编程

    千次阅读 多人点赞 2017-06-22 13:16:22
    博客核心内容:1.Socket是什么 2.基于TCP协议的网络编程模型(一)Socket是什么 1、C/S架构与socket的关系:我们学习socket就是为了完成C/S架构的开发 2、C/S架构的软件(软件属于应用层)是基于网络进行通信的,...
  • 假设使用Socket基于TCP通信协议进行C/S通信编程,客服端已经成功与服务端建立tcp连接,并且可以正常进行...那么客户端的recv()将会返回0; 如果服务端没有调用closesocket(sClient);而只调用WSACleanup();或直接关闭
  • socket返回值为0的问题

    万次阅读 2020-04-15 14:50:13
    socket_id为0,1,2的是给标准输入输出用的。当调用socket()来创建套接字时,返回值确实0,这时候如果进行读写,就是直接打印到控制台了。 二、什么情况下socket返回值为0 1. 如果我们调用close(0)之后,socket_id = 0...
  • NIO与Socket笔记 : Socket、NIO 理论

    千次阅读 2019-03-29 12:31:04
    一、Socket 理论 Socket编程其实就是实现服务端与客户端的数据通信,不管使用任何的编程语言, 在 实现上基本上都是4个步骤: 1建立连接;2请求连接; 3回应数据; 4结束连接,这4个 步骤的流程图如图 1-3所示。 ...
  • Flutter Socket实战

    千次阅读 热门讨论 2020-03-13 20:20:44
    其中包含了: 文字聊天 图片发送(查看) 选取图片 录视频 选取视频 发送语音 接下来就步入正题开始从头给读者介绍一下整个流程,由于本文章主要介绍Socket方面的功能,所以关于消息列表的代码我这里就不放出来了,...
  • 服务端在ubuntu服务器下,客户端在windows下,采用socket进行通信,在客户端接收数据时,出现了诡异的情况,recv返回值大于0,但缓冲区大小为0,代码如下:char buff[10]; int res=recv(ClientSocket, buff, 10, 0);...
  • 问题:java编写的socket服务端,C编写的客户端,通信的时候,C接收不到响应报文。 原因:服务端使用了readLine(),一直在等待客户端报文的结束符,造成阻塞。 处理办法:用缓存替换readLine(),具体代码如下: ...
  • 最近调试windows服务器 与客户端TCP连接遇到recv()出现立即返回,接收字符缓冲区为的问题。 花了一些时间,发现是客户端TCP断开就会出现这个问题 recv()之前用 setsockopt(sockConn,SOL_SOCKET,SO_RCVTIMEO,...
  • 如何在skynet框架中使用socket+protobuf。上篇 Skynet服务器框架(五) 使用pbc(protobuf) 我们已经大致了解了如何在Skynet中通过pcb来使用Protobuf,接下来我们开始了解skynet中有关Socket的部分。 API 几个...
  • java的socket多线程编程之关闭socket

    千次阅读 2019-12-05 12:14:29
    这两天在写socket通信,也就是下面的东西,然后遇到了个问题,怎样才能优雅的关闭socket(正常关闭而不是发生异常导致的关闭) 直接说思路吧,后面再说我遇到的问题! 我们这里说的关闭是用户点击断开按钮后再关闭...
  • socket通信中经常会遇到返回报文接收不全甚至完全没有接收到的问题。 二、解决方案: 发送方在报文头用固定长度的字节声明该报文正文长度,注意这里的报文正文不包括表示报文长度的字符串本身。接收方在接收报文时...
  • python之socket编程

    万次阅读 多人点赞 2019-06-06 15:00:31
    Socket是什么呢? socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,对于文件用【打开】【读写】【关闭】模式来操作。socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是...
  • socket.shutdownOutput()的理解

    千次阅读 2021-02-14 11:36:10
    看某神视频的时候,发现不用socket.shutdownOutput()服务端就会被阻塞,阻塞在如下代码块中: 后面想了下,其实在客户端代码中不调用socket.close()也会导致阻塞。 说回到客户端,如果不加如下代码就会阻塞。...
  • socket常用API详解

    千次阅读 2019-07-11 18:13:35
    一、socket概述 socket是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用已实现进程在网络中通信。 socket起源于UNIX,在Unix一切皆文件哲学的思想下,socket是一种...
  • Socket清空缓存区

    万次阅读 2019-01-10 10:13:00
    close一次socket,这个方案有效是有效,但这样的小问题还不至于如此大动干戈,因此不建议使用。 方案二 使用recv来读取,但是在阻塞模式下效率低下,因为在不知道数据的情况下,在最后一次读取的情况下需要等待到...
  • c语言实现socket服务端/客户端通过tcp传送文件
  • 本文先介绍了Socket通信技术以及TCP和UDP再通过一个完整示例实现了局域网内的聊天软件开发。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 101,277
精华内容 40,510
关键字:

发socket返回空