java与C之间的socket通信.docx
《java与C之间的socket通信.docx》由会员分享,可在线阅读,更多相关《java与C之间的socket通信.docx(6页珍藏版)》请在冰豆网上搜索。
java与C之间的socket通信
java和C#^间SOCKE通信的问题
一、服务器端(使用java编写)
/***监听客户端的请求
*/privatestaticvoidsocketService()
ExecutorServiceexec=Executors.newCachedThreadPool();
try
ServerSocketserver=newServerSocket(5678);
inti=1;
while(true)
MyLogManager.InfoLog(log,null,"等待连接第"+i+"个用
户...");
try
Socketclient=server.accept();
MyLogManager.lnfoLog(log,null,"第"+i+"个用户连接
完成!
");
exec.execute(newPDAServerWithDB(client));
catch(ExceptionwhileExp)
Stringmsg="多线程处理连接失败!
MyLogManager.ErrorLog(log,whileExp,msg);
i++;
catch(IOExceptionioe)
Stringmsg="连接失败!
";
MyLogManager.ErrorLog(log,ioe,msg);
exec.shutdown();
具体对于Socket信息的接受和发送在PDAServerWithDB类中处理信息处理分为:
接收数据和发送数据服务端接收数据一律采用ReadLine()方法,这就要求客户端在发送请求时要有行结束符。
服务器的接收发送数据的代码
a)。
构造输入输出流
InputStreaminPut=s.getInputStream();
OutputStreamoutPut=s.getOutputStream();
PrintWriteroutWriter=newPrintWriter(outPut);
BufferedReaderinputReader=newBufferedReader(new
InputStreamReader(inPut));
b。
接收客户端请求的代码
Stringrequest=inputReader.readLine();
request=request.trim();
request=request.replaceAll("\n","");
C。
向客户端发送文本数据的代码outWriter.println(strInfo);
outWriter.flush();
d)。
向客户端发送文件的代码//发送文件长度
Filefile=newFile(filePath);
byte[]outBytes=newbyte[1024];
intCount=0;
FileInputStreamfileInput=newFileInputStream(file);
ByteArrayOutputStreamow=newByteArrayOutputStream();
while((Count=fileInput.read(outBytes))>0){
MyLogManager.DebugLog(log,null,String.valueOf(Count));
ow.write(outBytes,0,count);
outPut.write(ow.toByteArray());
在C#客户端中无法响应。
//outWriter.flush();
二、客户端(使用java和C#两个版本)
1).发送请求信息(字符串格式)
对于JAVA来说:
直接使用PrintWrite类的println()方法即可。
而对于C#来说:
需要使用socket.Send(+"\r"));需要在请求信息
msg后面加上一个行结束标志符。
2).接收数据(文本或者文件)
2-1).java客户端接收数据
a)。
java接收文本的代码示例:
******代码示例*****log.info("开始连接服务器");
InetAddressaddress=InetAddress.getByName(AppConfig.IP);//;
SoCketChannelsC=SoCketChannel.open(new
InetSoCketAddress(address,AppConfig.PORT));
log.info("服务器连接成功");
//连接成功初始化流
InputStreaminputStream=Channels.newInputStream(sc);
InputStreamReaderis=new
InputStreamReader(inputStream,"GBK");
in=newBufferedReader(is);
log.info("接收服务器的数据");
StringresponseLine="";
while((responseLine=in.readLine())!
=null)
//用readLine接收数据是,会自动抛弃换行符,如果为了保持数据的格式,需要在这里加上一个换行标识符
returnStr+=responseLine+"\n";
log.info("接收服务器的数据完毕");
**************
b.)java接收文件的示例代码:
*****代码示例*****log.info("开始连接服务器");
InetAddressaddress=InetAddress.getByName("");//;
SocketChannelsc=SocketChannel.open(new
InetSocketAddress(address,AppConfig.PORT));
log.info("服务器连接成功,开始初始化流");
//连接成功初始化流
OutputStreamoutputStream=Channels.newOutputStream(sc);
InputStreaminputStream=Channels.newInputStream(sc);
InputStreamReaderinputStreamReader=new
InputStreamReader(inputStream);
byte[]b=newbyte[1024];
ByteArrayOutputStreambArrStream=new
ByteArrayOutputStream(fileLength);
intreadCount=0;
while((readCount=inputStream.read(b))!
=-1)log.info(readCount);
bArrStream.write(b,0,readCount);
log.info("size:
"+bArrStream.toByteArray().length);
log.info("接收服务器的数据完毕");
**************
2-2.)c#客户端接收数据的代码
a.)接收文本数据
*****代码示例*****
Socketsocket=null;
MemoryStreammemStream=null;
stringreturnMsg=string.Empty;
//与服务器建立连接
socket=newSocket(AddressFamily.InterNetwork,
SocketType.Stream,ProtocolType.Tcp);
IPAddressadd=IPAddress.Parse(appConfig.Ip);
IPEndPointendPt=newIPEndPoint(add,appConfig.Port);
socket.Connect(endPt);
//接收数据
byte[]buffer=newbyte[1024];
intrecCount=0;
memStream=newMemoryStream();
//接收返回的字节流
while((recCount=socket.Receive(buffer))>0)memStream.Write(buffer,0,recCount);
Encodingencoding=Encoding.GetEncoding("GBK");
returnMsg=encoding.GetString(memStream.GetBuffer(),0,memStream.GetBuffer().Length);
**************
b.)接收文件数据
****代码示例****//接收数据
byte[]buffer=newbyte[1024];
intrecCount=0;
MemoryStreammemStream=newMemoryStream();
while((recCount=socket.Receive(buffer))>0)memStream.Write(buffer,0,recCount);
II接下来按照文件格式,将memStrean保存为文件即可
**************
=以上是最终使用的代码版本
在开发过程中出现的问题及其解决
1.)文本乱码问题
java服务器端代码文件是使用GBK编码。
所以在客户端读取的时候
使用GBK编码进行转换。
2.)客户端和服务端的交互。
在服务端使用PrintWriter类来封装数据发送流(发送数据),new
BufferedReader(newInputStreamReader(InputStream))来封装输入流(读取数据)服务端读数据的时候是使用ReadLine方法,所以就要求客户端发送请求时需要有一个行结束标志。
对于java来说是用println()即可,
而对于C#则需要在发送信息的后面手动增加一个行结束标识符"\r"。
对于服务端的反馈信息有两种反馈方式,一个是println(),一个是
write(byte[])。
前者是文本的发送,后者是文件的发送。
在使用print(object)方法对文件发送时,java客户端可是正确的接
收数据,而C#客户端却不能,所以才采用了write(byte[])方法进行发送。
接收数据时,还要对按行发送的文本数据进行去尾处理这个处理java和C#一样,只是方法名的大小写不同
str=str.trim();
str=str.replaCeAll("\r","");
str=str.replaCeAll("\n","");
方法二:
DataOutputStream
Stringtemp=
publicstaticvoidSend(Stringcontent)throwsIOException
Sockets=newSocket(ip,port);
temp.getBytes();
out.writeInt(length);
out.write(b);
out=newDataOutputStream(s.getOutputStream());
,然后C#用只要监听端口
out.flush();}可以用上面的方法来发送到指定的端口就可以了,先接收一个int的报文长度然后new出一个byte[]然后再接收一个byte[],然后通过这个byte[]转换成String就可以了