linux tcp socket并发编程,调用accept函数后调用fork。两台电脑测试,为何accept返回的描述符是相同的?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux tcp socket并发编程,调用accept函数后调用fork。两台电脑测试,为何accept返回的描述符是相同的?相关的知识,希望对你有一定的参考价值。
可能是你的fork 之后产生的子进程拷贝的代码,它那里执行了accept,所以导致相同,你试着在每个fork之后的函数中用个exit(1);将子进程退出,然后应该就不会有这个问题了。 参考技术A 返回的描述符是当前可用的最小描述符,你测试环境下的两台电脑可用的最小描述符是一样的。追问accept返回的描述符不是唯一的么?我连台电脑同时连接,返回的描述符都是4.
追答这个就比较奇怪了,两个client都能和server正常通信吗?同时。
追问单独是可以的,但是如果同时开两个必然不好使。。。描述符都一样
追答那可能就是你程序有问题。
[javaSE] 网络编程(TCP-并发上传图片)
客户端:
1.服务端点
2.读取客户端已有的图片数据
3.通过socket输出流将数据发给服务端
4.读取服务端反馈信息
5.关闭
获取Socket对象,new出来,构造参数:String的服务端ip,int的端口号
调用Socket对象的getOutputStream()方法,得到OutputStream输出流对象
获取FileInputStream对象,new出来,构造参数:String的文件路径
while循环调用,条件FileInputStream对象的read()方法,读取到字节数组中
循环中,调用OutputStream输出流对象的write()方法,写入数据,参数:byte[],0,len
调用Socket对象的shutDownOutput()方法,通知服务端写入完成
调用Socket对象的getInputStream()方法,得到InputStream输入流对象
调用InputStream输入流对象的read()方法,读取,并打印
调用FileInputStream对象的close()方法
调用Socket对象的close()方法
服务端:
正常读取
解决并发
上面的例子,一次只能有一个客户端服务,解决并发上传的问题,使用多线程处理每个来访的客户
定义一个类PicThread,实现Runnable接口
定义构造函数,传递进来Socket对象
实现run()方法,在try-catch中捕获异常,正常读取Socket对象的流
解决文件覆盖
文件的名称采用ip+(数字),例如:192.168.1.100(2).jpg
获取ip 方法,socket.getInetAddress().getHostAddress()
第一次进入,文件名192.168.1.100.jpg
第二次进入,判读文件已存在,文件名变成192.168.1.100(1).jpg
主函数传值形式并判断
判断有一个参数 arg.length==1
判断是文件,并且存在 File对象的exists()方法和isFile()方法
判断文件后缀,File对象的getName().endsWith(“.jpg”)方法
判断文件大小,File对象的length()方法
import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; import java.net.UnknownHostException; class UploadPicClient { /** * @param args * @throws IOException * @throws UnknownHostException */ public static void main(String[] args) throws Exception { //判断参数 if(args.length!=1){ System.out.println("请选择一个文件"); return; } File file=new File(args[0]); if(!file.exists()||!file.isFile()){ System.out.println("请选择一个存在的文件"); return; } if(!file.getName().endsWith(".png")||file.length()>(1024*1024)){ System.out.println("请选择小于1M的png文件"); return; } Socket socket = new Socket("127.0.0.1", 10001); OutputStream out = socket.getOutputStream(); // 输出 FileInputStream fileInputStream = new FileInputStream("E:/11.png"); byte[] b = new byte[1024]; int len = 0; while ((len = fileInputStream.read(b)) != -1) { out.write(b, 0, len); } // 通知服务端 socket.shutdownOutput(); // 接收反馈 InputStream inputStream = socket.getInputStream(); byte[] res = new byte[1024]; len = inputStream.read(res); System.out.println(new String(res, 0, len)); out.close(); socket.close(); } } /** * 多线程上传 * @author taoshihan * */ class UploadPicServerThread implements Runnable { private Socket socket; public UploadPicServerThread(Socket s) { this.socket = s; } @Override public void run() { // 读取 InputStream is; try { is = socket.getInputStream(); byte[] res = new byte[1024]; int len = 0; // 解决文件覆盖 String ip = socket.getInetAddress().getHostAddress(); int fileNum = 1; File file = new File(ip + ".png"); while (file.exists()) { file = new File(ip + "(" + (fileNum++) + ").png"); } FileOutputStream fos = new FileOutputStream(file); while ((len = is.read(res)) != -1) { fos.write(res, 0, len); } // 反馈 OutputStream os = socket.getOutputStream(); os.write("上传成功!".getBytes()); is.close(); os.close(); fos.close(); } catch (Exception e) { e.printStackTrace(); } } } // 服务端 public class UploadPicServer { /** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { ServerSocket serverSocket = new ServerSocket(10001); while (true) { Socket socket = serverSocket.accept(); new Thread(new UploadPicServerThread(socket)).start(); } } }
以上是关于linux tcp socket并发编程,调用accept函数后调用fork。两台电脑测试,为何accept返回的描述符是相同的?的主要内容,如果未能解决你的问题,请参考以下文章