网络字节序 返回的数据封装格式是:数据长度|数据,其中数据长度是网络字节顺序编码。数据长度是4个字节,代表数据部分的长度。java客户端怎样接受c服务端发送过来的数据,并写到指定的文件中?麻烦各位了,希望给出相应代码,谢谢了! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 import java.io.File;import java.io.FileOutputStream;import java.io.InputStream;import java.net.Socket;public class Test { /** * @param args * @throws * @throws Exception */ public static void main(String[] args) throws Exception { Socket socket = new Socket("127.0.0.1",3306); InputStream is = socket.getInputStream(); int count = 0; byte[] data = new byte[1024]; byte[] head = new byte[4]; count = is.read(head); if(count == 4){ FileOutputStream fos = new FileOutputStream(new File("c:/1.txt")); while((count = is.read(data))!= -1){ fos.write(data,0,count); } fos.flush(); fos.close(); } }} 前天刚写了一个,对方服务端是用c写的,我作为客户端用java写,数据格式要看对方是怎么定义的,根据数据封装来实现:举个例子:对方的数据封装格式为:包长#begin,field1,field 2,……,fieldn#end包长字段 中文含义 数据类型 字节数 备注包长度 WORD 2 低位在前,高位在后包长采用2个字节,低位在前,高位在后。服务端封包方法:数据包长度:数据包包长为二进制格式, 低位在前,高位在后,包长不包含长度值自己。以c程序打包过程为例如下Void MakePacket(char* buff, int buff_size, const char* a_string){ int len = 0; memset(buff, 0, buff_size); strcpy(&buff[2], a_string); /* 将包的前后置包的长度(不包含长度本身) */ len = strlen(a_string); buff[0] = buff[len + 2] = len % 256; /* 低位在前 */ buff[1] = buff[len + 3] = len / 256; /* 高位在后 */ }java 获取数据包://读取数据包长,根据约定包长占2个字节 byte[] getBytes = new byte[2]; int len = client.getInputStream().read(getBytes); if (len > 0) { //声明要读取数据的字节数组,通过包长定数组大小 int pLen = getByteToInt(getBytes); //通过读取对方包头,把包头转化为int型 byte[] alarm = new byte[pLen]; client.getInputStream().read(alarm); //读取包尾,因为数据包后面还包括包长,所以获取丢弃 client.getInputStream().read(getBytes); String msg = new String(alarm); //获取到的对方数据,不包括包长 //......写入到文件中 }其中getByteToInt /** * 将字节数组转成整型 * @param b byte[] 字节数组 * @return int 字节数组转化后的整型值 */ public static int getByteToInt(byte[] b) { int result = b[1] & 0xff; result = (result << 8) + (b[0] & 0xff); return result; }楼主是4个字节的: /** * 将字节数组转成整型 * * @param b * byte[]字节数组 * @return int 字节数组转化后的整型值 */ public static int getByteToInt(byte[] b) { int result = b[3] & 0xff; result = (result << 8) + (b[2] & 0xff); result = (result << 8) + (b[1] & 0xff); result = (result << 8) + (b[0] & 0xff); return result; }注:网络字节是采用低位在前,高位在后的原则,而主机字节是采用高位在前,低位在后的。如果需要跟对方交互,比如需要给对方返回接收到的信息包,看是否也要封装成以上格式,如果需要,则应该把包长转化为网络字节:具体见:http://blog.csdn.net/hye4/archive/2008/06/06/2517342.aspx 以上代码就改一个数据包长度为4.把这个注释掉client.getInputStream().read(getBytes); 没什么事情做,瞒写了。/** * <p>Title: </p> * * <p>Description: </p> * * <p>Copyright: Copyright (c) 2008</p> * * <p>Company: </p> * * @author not attributable * @version 1.0 */import java.net.Socket;import java.io.IOException;import java.io.FileOutputStream;import java.io.OutputStream;import java.io.*;public class FileClient extends Thread { private final int port = 8000; private final String host = "localhost"; private Socket socket; private static String fileName; FileClient() throws IOException { socket = new Socket(host, port); System.out.println("连接服务器成功"); } public void run() { //一直读取数据 while (true) { // 读取数据包长 byte[] getBytes = new byte[4]; int len = 0; OutputStream fileIn = null; try { fileIn = new FileOutputStream("f:\\" + fileName); } catch (FileNotFoundException ex1) { } try { len = socket.getInputStream().read(getBytes); //如果正常读取len等于4,表示4个字节 if (len > 0) { // 声明要读取数据的字节数组,通过包长定数组大小 int pLen = getByteToInt(getBytes); //读取包长,转化为整型数据 //声明数据包字节数组,读取数据 byte[] alarm = new byte[pLen]; socket.getInputStream().read(alarm); String msg = new String(alarm); //把数据写入文件中 fileIn.write(msg.getBytes()); fileIn.flush(); } fileIn.close(); } catch (IOException ex) { ///............. } } } /** * 将字节数组转成整型 * * @param b * byte[]字节数组 * @return int 字节数组转化后的整型值 */ private int getByteToInt(byte[] b) { int result = b[3] & 0xff; result = (result << 8) + (b[2] & 0xff); result = (result << 8) + (b[1] & 0xff); result = (result << 8) + (b[0] & 0xff); return result; } public static void main(String[] args) { try { FileClient fileclient = new FileClient(); fileclient.start(); } catch (IOException ex) { } }} 字节 fileIn.write(msg.getBytes()); fileIn.flush(); 循环命名对象 Sdk 在线等:这3个程序问题怎么解决呢? 在一个类中如何获得调用类的类名,和方法名 如何判断一个字符串只有数字(0123456789)和运算符(+-*/^%) 达人请教一段程序实现:在一个面板上鼠标点击一次,在该点显示一个随机颜色 关于数据库操作的N层架构问题 为什么会出错,大家快来拿人,容易题目 WINDOWS ME 怎样设置Path 求教代理服务器的问题 跪求java高手 帮忙 本人 菜鸟!! JAVA操作定时任务
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.Socket;
public class Test { /**
* @param args
* @throws
* @throws Exception
*/
public static void main(String[] args) throws Exception {
Socket socket = new Socket("127.0.0.1",3306);
InputStream is = socket.getInputStream();
int count = 0;
byte[] data = new byte[1024];
byte[] head = new byte[4];
count = is.read(head);
if(count == 4){
FileOutputStream fos = new FileOutputStream(new File("c:/1.txt"));
while((count = is.read(data))!= -1){
fos.write(data,0,count);
}
fos.flush();
fos.close();
}
}
}
举个例子:
对方的数据封装格式为:包长#begin,field1,field 2,……,fieldn#end包长字段 中文含义 数据类型 字节数 备注
包长度 WORD 2 低位在前,高位在后包长采用2个字节,低位在前,高位在后。服务端封包方法:
数据包长度:数据包包长为二进制格式, 低位在前,高位在后,包长不包含长度值自己。以c程序打包过程为例如下
Void MakePacket(char* buff, int buff_size, const char* a_string)
{
int len = 0;
memset(buff, 0, buff_size);
strcpy(&buff[2], a_string);
/* 将包的前后置包的长度(不包含长度本身) */
len = strlen(a_string);
buff[0] = buff[len + 2] = len % 256; /* 低位在前 */
buff[1] = buff[len + 3] = len / 256; /* 高位在后 */
}java 获取数据包://读取数据包长,根据约定包长占2个字节
byte[] getBytes = new byte[2];
int len = client.getInputStream().read(getBytes);
if (len > 0) {
//声明要读取数据的字节数组,通过包长定数组大小
int pLen = getByteToInt(getBytes); //通过读取对方包头,把包头转化为int型
byte[] alarm = new byte[pLen];
client.getInputStream().read(alarm);
//读取包尾,因为数据包后面还包括包长,所以获取丢弃
client.getInputStream().read(getBytes);
String msg = new String(alarm); //获取到的对方数据,不包括包长
//......写入到文件中
}
其中getByteToInt
/**
* 将字节数组转成整型
* @param b byte[] 字节数组
* @return int 字节数组转化后的整型值
*/
public static int getByteToInt(byte[] b)
{
int result = b[1] & 0xff;
result = (result << 8) + (b[0] & 0xff);
return result;
}
楼主是4个字节的:
/**
* 将字节数组转成整型
*
* @param b
* byte[]字节数组
* @return int 字节数组转化后的整型值
*/
public static int getByteToInt(byte[] b)
{
int result = b[3] & 0xff;
result = (result << 8) + (b[2] & 0xff);
result = (result << 8) + (b[1] & 0xff);
result = (result << 8) + (b[0] & 0xff);
return result;
}注:网络字节是采用低位在前,高位在后的原则,而主机字节是采用高位在前,低位在后的。
如果需要跟对方交互,比如需要给对方返回接收到的信息包,看是否也要封装成以上格式,如果需要,则应该把包长转化为网络字节:
具体见:http://blog.csdn.net/hye4/archive/2008/06/06/2517342.aspx
* <p>Title: </p>
*
* <p>Description: </p>
*
* <p>Copyright: Copyright (c) 2008</p>
*
* <p>Company: </p>
*
* @author not attributable
* @version 1.0
*/
import java.net.Socket;
import java.io.IOException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.*;public class FileClient extends Thread {
private final int port = 8000;
private final String host = "localhost";
private Socket socket;
private static String fileName; FileClient() throws IOException {
socket = new Socket(host, port);
System.out.println("连接服务器成功");
} public void run() { //一直读取数据
while (true) {
// 读取数据包长
byte[] getBytes = new byte[4];
int len = 0;
OutputStream fileIn = null;
try {
fileIn = new FileOutputStream("f:\\" +
fileName);
} catch (FileNotFoundException ex1) {
}
try {
len = socket.getInputStream().read(getBytes); //如果正常读取len等于4,表示4个字节
if (len > 0) {
// 声明要读取数据的字节数组,通过包长定数组大小
int pLen = getByteToInt(getBytes); //读取包长,转化为整型数据 //声明数据包字节数组,读取数据
byte[] alarm = new byte[pLen];
socket.getInputStream().read(alarm); String msg = new String(alarm);
//把数据写入文件中
fileIn.write(msg.getBytes());
fileIn.flush();
}
fileIn.close();
} catch (IOException ex) {
///.............
} }
} /**
* 将字节数组转成整型
*
* @param b
* byte[]字节数组
* @return int 字节数组转化后的整型值
*/
private int getByteToInt(byte[] b) {
int result = b[3] & 0xff;
result = (result << 8) + (b[2] & 0xff);
result = (result << 8) + (b[1] & 0xff);
result = (result << 8) + (b[0] & 0xff);
return result;
} public static void main(String[] args) {
try {
FileClient fileclient = new FileClient();
fileclient.start();
} catch (IOException ex) {
}
}
}
fileIn.flush();