一.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大多采用小端字节序,所以小端字节序又被称为主机字节序,大端字节序也称为网络字节序。