终端通过GPRS发送UDP数据到固定IP:端口号,socket recvfrom接收不到数据,但却有返回值,如何解决

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了终端通过GPRS发送UDP数据到固定IP:端口号,socket recvfrom接收不到数据,但却有返回值,如何解决相关的知识,希望对你有一定的参考价值。

通过PC发送,服务器可以接收到数据,recvfrom 的返回值与PC发送的数据包长度相等。
但是通过设备的GPRS模块发送的UDP数据包,却接收不到,recvfrom 函数却有返回值,返回值刚好等于UDP数据包的长度。

PC端UDP发送代码:
char *pPack="0000000AS DFKJASLD FJASDKLFJSLAFJAALSDJFKLASDJFLASDFJLASF123";
sprintf(sendBuff,"Message %d is: ok",ncount++); //将ncount的值放入字符串senBuff中
sendto ( sockListener,/*sendBuff*/pPack,strlen(pPack), 0, (SOCKADDR *) &saUdpServ, sizeof (SOCKADDR_IN));

接收代码如下:
WSADATA wsaData; //指向WinSocket信息结构的指针
SOCKET sockListener;
SOCKADDR_IN sin,saClient; //设置两个地址,sin用来绑定

char cRecvBuff[10000]=0; //定义接收缓冲区
int nSize,nbSize;
int iAddrLen=sizeof(saClient);
if(WSAStartup(MAKEWORD( 1, 1 ), &wsaData )!=0) //进行WinSocket的初始化

printf("Can't initiates windows socket!Program stop.\n");//初始化失败返回-1
return -1;

sockListener=socket(AF_INET, SOCK_DGRAM,0);
sin.sin_family = AF_INET;
sin.sin_port = htons(udp_recv_port); //对某一端口进行监听,可以根据需要更改
sin.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind( sockListener, (SOCKADDR FAR *)&sin, sizeof(sin))!=0)

printf("Can't bind socket to local port!Program stop.\n");//初始化失败返回-1
return -1;

while(TRUE)

nSize = sizeof ( SOCKADDR_IN );
if((nbSize=recvfrom (sockListener, cRecvBuff,10000,0,(SOCKADDR FAR *) &saClient,&nSize))==SOCKET_ERROR) //若接收失败则提示错误

printf("Recive Error");
break;

printf("nbsize="); printf("%d",nbSize);
printf("//cRecvBuff=");
printf("%s",cRecvBuff);
图片中上面三组是PC发的数据,下面两组是GPRS终端发的数据。仅有返回值18.却没数据。

参考技术A UDP是非连接的,发送的报文虽然发送出去了,但是服务器不一定保证接收到。你的有返回值说明你发送出去了,但是不代表服务端收到。还明白。 参考技术B 代码没啥问题,不知道GPRS发送代码是怎样的追问

GPRS的代码我也不知道,看了下硬件,是SIM900

追答

if((nbSize=recvfrom (sockListener, cRecvBuff,10000,0,(SOCKADDR FAR *) &saClient,&nSize))==SOCKET_ERROR) 设置一个断点,看到底cRecvBuff中是什么!

本回答被提问者采纳
参考技术C 不太懂,你可以在说的详细些吗追问

哪里没说明白?

UDP网络编程

UDP 网络通信
 类 DatagramSocket 和 DatagramPacket 实现了基于 UDP 协议网络程序。
 UDP数据报通过数据报套接字 DatagramSocket 发送和接收,系统不保证
UDP数据报一定能够安全送到目的地,也不能确定什么时候可以抵达。
 DatagramPacket 对象封装了UDP数据报,在数据报中包含了发送端的IP
地址和端口号以及接收端的IP地址和端口号。
 UDP协议中每个数据报都给出了完整的地址信息,因此无须建立发送方和
接收方的连接。如同发快递包裹一样。

 

 

DatagramSocket 类的常用方法
 public DatagramSocket(int port)创建数据报套接字并将其绑定到本地主机上的指定端口。套接字将被
绑定到通配符地址,IP 地址由内核来选择。
 public DatagramSocket(int port,InetAddress laddr)创建数据报套接字,将其绑定到指定的本地地址。
本地端口必须在 0 到 65535 之间(包括两者)。如果 IP 地址为 0.0.0.0,套接字将被绑定到通配符地
址,IP 地址由内核选择。
 public void close()关闭此数据报套接字。
 public void send(DatagramPacket p)从此套接字发送数据报包。DatagramPacket 包含的信息指示:将
要发送的数据、其长度、远程主机的IP 地址和远程主机的端口号。
 public void receive(DatagramPacket p)从此套接字接收数据报包。当此方法返回时,DatagramPacket
的缓冲区填充了接收的数据。数据报包也包含发送方的 IP 地址和发送方机器上的端口号。 此方法
在接收到数据报前一直阻塞。数据报包对象的 length 字段包含所接收信息的长度。如果信息比包的
长度长,该信息将被截短。
 public InetAddress getLocalAddress()获取套接字绑定的本地地址。
 public int getLocalPort()返回此套接字绑定的本地主机上的端口号。
 public InetAddress getInetAddress()返回此套接字连接的地址。如果套接字未连接,则返回null。
 public int getPort()返回此套接字的端口。如果套接字未连接,则返回-1。

 

 

 

 

 

 

 

 

 

 

package com.atguigu.java1;

import org.junit.Test;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

/**
 * UDP协议的网络编程
 * @author CH
 * @create 2021 下午 4:34
 */
public class UDPTest {

    //发送端
    @Test
    public void sender() throws IOException {

        DatagramSocket socket = new DatagramSocket();



        String str = "我是UDP方式发送的导弹";
        byte[] data = str.getBytes();
        InetAddress inet = InetAddress.getLocalHost();
        DatagramPacket packet = new DatagramPacket(data,0,data.length,inet,9090);

        socket.send(packet);

        socket.close();

    }
    //接收端
    @Test
    public void receiver() throws IOException {

        DatagramSocket socket = new DatagramSocket(9090);

        byte[] buffer = new byte[100];
        DatagramPacket packet = new DatagramPacket(buffer,0,buffer.length);

        socket.receive(packet);

        System.out.println(new String(packet.getData(),0,packet.getLength()));

        socket.close();
    }
}

 

以上是关于终端通过GPRS发送UDP数据到固定IP:端口号,socket recvfrom接收不到数据,但却有返回值,如何解决的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 NAT 通过公共 IP 发送 UDP 数据包?

UDP与IP分片

Linux| |对于UDP的学习UDP(用户数据报协议)

UDP:用户数据报协议

TCP/IP详解UDP用户数据报协议

UDP网络编程