关于socket流传输的问题

zouxinfox 2007-04-26 10:30:42
有一个问题一直不太明白,我想写一个客户端通过socket流向服务端传输文件的程序。 我想先传输文件名,文件长度,再传输文件内容。可是如果在客户端向流中依次写入这三个部分,那么服务端如何在流中区分开文件名,文件长度和文件内容?
...全文
1309 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
qingyuan18 2007-04-26
  • 打赏
  • 举报
回复
楼主我建议你把要通过socket传的东西封装成一个类,文件的大小,名字都做为整个类的变量,将这个类序列化,通过ObjectOutputStream流来写入,这样就不会出现你说的问题了
brooksychen 2007-04-26
  • 打赏
  • 举报
回复
当午理解错了,我说的是作为一个流,三部分之间用分隔符隔开,或者就固定长度,比如文件名固定为256字节,长度固定为10字节,剩下的都是内容。
brooksychen 2007-04-26
  • 打赏
  • 举报
回复
一般来说,这种传输是会固定格式的,就像很多协议定义的那样
你随便看看像SMTP协议等协议的格式就明白了
masse 2007-04-26
  • 打赏
  • 举报
回复
分开发的设计不太合理。
masse 2007-04-26
  • 打赏
  • 举报
回复
这个涉及在并发的时候有问题吧
比如两个客户端同时发,
可能会有错。
brooksychen 2007-04-26
  • 打赏
  • 举报
回复
你可以用一个文件名、内容中不包含的字符(或字符串)作为分隔符来分开。
zouxinfox 2007-04-26
  • 打赏
  • 举报
回复
多谢大家,现在我完全理解了
CrazyGou 2007-04-26
  • 打赏
  • 举报
回复
协议!
bq110 2007-04-26
  • 打赏
  • 举报
回复
发段代码
服务器
import java.io.*;
import java.net.*;
import java.util.*;
import enroll.EnrollInfo;
public class Main
{
public static void main(String[] args)
{
try
{
//创建连接
ServerSocket socket = new ServerSocket(7002);
while(true)
{
int counter=1;
//连接
Socket incoming=socket.accept();
System.out.println(counter);
Runnable r=new ThreadeEchoHand(incoming,counter);
Thread t=new Thread(r);
t.start();
counter++;
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
class ThreadeEchoHand implements Runnable//线程类
{
private Socket incoming;
private int counter;
public ThreadeEchoHand(Socket incoming, int counter)
{
this.incoming=incoming;
this.counter=counter;
}
public void run()
{
try
{
try
{
//输入流和输出流连接incoming
InputStream inStream=incoming.getInputStream();
OutputStream outStream=incoming.getOutputStream();
//用输入流得到数据
ObjectInputStream inobj=new ObjectInputStream(inStream);
//用输出流输出数据
ObjectOutputStream outobj=new ObjectOutputStream(outStream);
try
{
//读一段数据
EnrollInfo n=(EnrollInfo)inobj.readObject();
System.out.println(n.toString());
//System.out.println(incoming.getLocalPort());
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
}
finally{incoming.close();}//关闭流
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
客户端
import java.io.*;
import java.net.*;
import java.sql.*;

import enroll.EnrollInfo;
public class Na
{

public Na()
{
ObjectOutputStream o=null;
Socket socket1=null;
try {
socket1 = new Socket("127.0.0.1", 7002);
//输入流和输出流连接incoming
OutputStream outStream=socket1.getOutputStream();
o=new ObjectOutputStream(outStream);
EnrollInfo nn=new EnrollInfo("name","asas",new Date(19820208), "3423", "3123", "324", "3424", "4234");
o.writeObject(nn);
o.flush();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//关闭流
finally{try {
o.close();
socket1.close();
} catch (IOException e) {
e.printStackTrace();
}}

}
public static void main(String[] args)
{
Na a=new Na();
}
}
包文件
package enroll;

import java.io.*;
import java.sql.*;

//注册信息
public class EnrollInfo implements Serializable//必须继承此接口才能被传输
{
private String name;//昵称
private String pass;//密码
private Date day;//生日
private String sex;//性别
private String constellation;//星座
private String attribute;//生肖
private String dwellingPlace;//省份
private String consciousness;//个人说明
public EnrollInfo(String name, String pass, Date day, String sex, String constellation, String attribute, String dwellingPlace, String consciousness)
{
this.name = name;
this.pass = pass;
this.day = day;
this.sex = sex;
this.constellation = constellation;
this.attribute = attribute;
this.dwellingPlace = dwellingPlace;
this.consciousness = consciousness;
}
public String getAttribute() {
return attribute;
}
public void setAttribute(String attribute) {
this.attribute = attribute;
}
public String getConsciousness() {
return consciousness;
}
public void setConsciousness(String consciousness) {
this.consciousness = consciousness;
}
public String getConstellation() {
return constellation;
}
public void setConstellation(String constellation) {
this.constellation = constellation;
}
public Date getDay() {
return day;
}
public void setDay(Date day) {
this.day = day;
}
public String getDwellingPlace() {
return dwellingPlace;
}
public void setDwellingPlace(String dwellingPlace) {
this.dwellingPlace = dwellingPlace;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPass() {
return pass;
}
public void setPass(String pass) {
this.pass = pass;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String toString()
{
return "姓名"+this.name+"生日"+this.day;
}
}
刚写的!没有问题!你看看把
maquan 2007-04-26
  • 打赏
  • 举报
回复
楼主问的问题实际上是“通信协议”的问题。

socket 通信程序一般都是需要制定通信协议的,只不过有时候比较简单,就不用特别描述了(比如,如果只传文件内容,那么,不用特别去讲通信协议是怎么怎么样的了。这时候,并不是没有通信协议,而是有一个特别简单的协议)。

对于楼主说的这种情况,就需要对通信协议做一个明确描述了。至于具体内容是什么,完全可以自己定义。比如:“从第一个字节开始,是一个 null-terminated 的 UTF8 字符串,表示文件名;紧跟着 8 个字节表示文件的字节长度(高位在前,低位在后);然后紧跟着的是文件内容,字节数是前面确定的文件长度值”。

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧