udp通信之c为客户端android为服务端

一.android添加权限

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>

二.c为客户端发送数据

//结构体数据如下:
typedef struct {
	int cmd; //  消息类型(1.开始 2.传送内容 3.结束)
	int len;
	char buf[0]; //内容
}subtitle_t;

typedef struct {
	int pos_x; //播放器窗口信息,apk根据播放器窗口(surfaceview)位置信息
	int pos_y; //计算合适的渲染位置;
	int width;
	int height;
}sub_position;

// 发送数据的函数
// 将结构体sub_position放到subtitle_t的buf中发送过去
void sendSubtitleStart(int sockfd,struct sockaddr_in* pDestAddr,socklen_t stlen) 
{
	subtitle_t *pSubtitle;
	sub_position pos;
	memset(&pos,0,sizeof(pos));

	pos.pos_x = 10;
	pos.pos_y = 20;
	pos.width = 1280;
	pos.height = 720;
  
	pSubtitle = (subtitle_t *)malloc(sizeof(subtitle_t) + sizeof(sub_position));
	if(NULL == pSubtitle) {
		Log(LOG_LEVEL_ERR,"##### #### malloc fail #####");
		return ;
	}
	memset(pSubtitle,0,sizeof(subtitle_t) + sizeof(sub_position));
	
	pSubtitle->cmd = 1;
	pSubtitle->len = sizeof(sub_position);
	memcpy(pSubtitle->buf,&pos,pSubtitle->len);
	printf("##### #### pSubtitle->cmd:%d", pSubtitle->cmd);
        printf("##### #### send init #####");
	
	sendto(sockfd,pSubtitle,sizeof(subtitle_t) + sizeof(sub_position),0,(struct sockaddr*)pDestAddr,stlen);

}

//main中代码如下:
int main(){
    int sockfd;/*cocket句柄和接受到连接后的句柄 */
    char buf[MAX_DATA];//储存接收数据 
    int n = -1;
    
    sockfd = socket(AF_INET,SOCK_DGRAM,0);/*建立socket SOCK_STREAMSOCK_DGRAM*/ 
    if(sockfd == -1){
        Log(LOG_LEVEL_ERR,"socket failed:%d",errno);
    	return -1;
     }

    //参数意义见上面服务器端 
  struct sockaddr_in dest_addr;/*目标地址信息*/
  memset(&dest_addr,0,sizeof(struct sockaddr_in));
    dest_addr.sin_family=AF_INET;
    dest_addr.sin_port=htons(DEST_PORT);
    dest_addr.sin_addr.s_addr=inet_addr(DEST_IP);
    socklen_t stlen = sizeof(struct sockaddr_in);


    while(1){
	printf("请输入一个数字,开始发送数据:");        
	char buf=0;         
	scanf("%hhd",&buf);
	sendSubtitleStart(sockfd,&dest_addr, stlen); 
	printf("send success");*/
     }
}

三.服务端接收数据

new Thread(new Runnable() {
            @Override
            public void run() {
                int port = 8913;
                byte[] buf = new byte[512];
                DatagramPacket packet = new DatagramPacket(buf,buf.length);
                try{
                    //1.获取 datagramSocket 实例,并监听某个端口
                    DatagramSocket socket = new DatagramSocket(port);
                    Log.d(TAG,"new socket");
                    while (true) {
                        //2.创建一个 udp 的数据包
                        Log.d(TAG,"server将一直等待连接的到来");
                        socket.receive(packet);
                        Log.d(TAG,"=====================");
                        String ip = packet.getAddress().getHostAddress();
                        port = packet.getPort();
                        Log.d(TAG,"客户端: "+ip+"\tport: "+port);
                        ByteArrayInputStream bis = new ByteArrayInputStream(packet.getData(),0,packet.getLength());
                        DataInputStream dis = new DataInputStream(bis);
                        Log.d(TAG,"cmd: " + int_EndianBigtoLittle(dis.readInt()));
                        Log.d(TAG,"len: " + int_EndianBigtoLittle(dis.readInt()));
                        Log.d(TAG,"x: " + int_EndianBigtoLittle(dis.readInt()));
                        Log.d(TAG,"y: " + int_EndianBigtoLittle(dis.readInt()));
                        Log.d(TAG,"w: " + int_EndianBigtoLittle(dis.readInt()));
                        Log.d(TAG,"h: " + int_EndianBigtoLittle(dis.readInt()));
                    }
                } catch (Exception e) {

                }
            }
        }).start();

// 在网落传送过程中存在大小端问题,int float需要转换
 private static int int_EndianBigtoLittle(int value)
    {
        byte[] src = new byte[4];
        src[0] = (byte) ((value>>24)&0xFF);
        src[1] = (byte) ((value>>16)&0xFF);
        src[2] = (byte) ((value>>8)&0xFF);
        src[3] = (byte) ((value)&0xFF);
        return (int) ((src[0]&0xFF)|((src[1]&0xFF)<<8)|((src[2]&0xFF)<<16)|((src[3]&0xFF)<<24));
    }

输出结果

注意:

  字节序分为大端字节序和小端字节序,现代PC大多采用小端字节序,所以小端字节序又被称为主机字节序,大端字节序也称为网络字节序。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值