我听说你还不知道如何进行Socket 编程

博客:https://www.jianshu.com/p/b04930d2b85e上周我们描述了传输层协议TCP、UDP,但它们毕竟只是协议,看不见摸不着,那我

这篇文章给大家聊聊关于我听说你还不知道如何进行Socket 编程,以及对应的知识点,希望对各位有所帮助,不要忘了收藏本站哦。

插座概览

Socket在中文里就是插座的意思。专业术语叫socket。它将TCP/IP封装成调用接口供开发者调用。也就是说开发者可以通过调用Socket相关的API来实现网络通信。 Java中也有Socket相关的API,主要分为两种,即基于UDP传输协议的Socket和基于TCP传输协议的Socket。本文将详细介绍基于这两种传输协议的Socket。

UDP套接字

发件人:

发送方开始.接收方:

接收方开始.地址:/192.168.31.137—端口:65037—内容:你今天背单词成功收到消息了吗,打印出了发送方IP和端口。让我引导您完成以下步骤。

发件人:

首先创建一个udp套接字服务,并将要发送的数据放入数据包DatagramSocket中。 DatagramSocket会按照UDP协议封装数据包、IP、端口号,通过udp socket服务发送数据包。最后,关闭接收方的udp服务:

创建一个udp套接字服务并明确其端口号。创建一个DatagramSocket 来解析数据。接收数据包。接收数据放入数据包中。通过DatagramSocket解析数据。关闭服务。整个UDP数据发送过程就是这样。

笔记:

由于UDP是无连接且不可靠的传输,接收方需要在发送方发送数据之前启动,否则将无法接收到数据,这意味着必须先运行UDPSocketReceive,然后运行UDPSocketSend。

聊天实例

我们看一下打印的结果:

UDP套接字1

UDPSocket 接收器启动.UDPSocket Receive:hello udp1heelo udp2UDPSocket2

UDPSocket2 接收器启动.hello udp1UDPSocket2 Receive:hello udp2 我在UDPSocket1 的控制台中输入:“hello udp2”,在UDPSocket2 的控制台中输入“hello udp1”。接收到的内容和发送的内容是一模一样的,一个简单的聊天功能就已经实现了。希望不熟悉的朋友也可以敲下代码再练习一下。

TCP套接字

TCP是一种基于客户端-服务器的可靠的面向连接的传输。上一篇文章我们也讲解了TCP安全传输机制,相当复杂。如果个人需要封装TCP协议,对于大多数开发者来说显然很难实现,所以Java也为开发者提供了基于TCP的Socket。与UDP不同的是,TCP Socket分为Socket和ServerSocket,分别对应客户端和服务器。我用代码实现一个简单的TCP通信功能:

客户:

//客户端public class TCPClient { public static void main(String[] args) throws IOException { //1.创建TCP客户端Socket服务Socket client=new Socket(); //2.与服务器连接InetSocketAddress 地址=new InetSocketAddress(‘192.168.31.137’,10000);客户端.connect(地址); //3.连接成功后,获取客户端Socket输出流OutputStream outputStream=client.getOutputStream(); //4.将输出流传递给服务器写入数据outputStream.write(‘hello server’.getBytes()); //5.关闭流client.close();首先创建一个Socket和InetSocketAddress,然后通过Socket的connect()方法进行连接,连接成功后可以获得输出流,通过该输出流可以将数据传输到服务器。

我听说你还不知道如何进行Socket 编程

服务器:

public class TCPServer { public static void main(String[] args) throws IOException { //1.创建服务器Socket并指定端口号ServerSocket serverSocket=new ServerSocket(10000); //2.获取客户端的Socket Socket socket=serverSocket.accept(); //3.通过客户端的Socket获取输入流InputStream inputStream=socket.getInputStream(); //4.通过输入流获取客户端传入的数据BufferedReader bufferedReader=new BufferedReader(new InputStreamReader( inputStream));字符串行=空; while ((line=bufferedReader.readLine())!=null){ System.out.println(line); } //5.关闭流socket.close(); serverSocket.close();首先创建一个服务端Socket并指定端口号,通过accept()方法获取链接的客户端Socket,从客户端Socket获取输入流,最后从输入流中读取客户端传输的数据。

我们看一下服务器端的打印结果:

hello 服务器成功接收到客户端的数据

笔记:

一个服务器可以同时与多个客户端通信,那么它如何区分不同的客户端呢?从上面的代码我们可以看到,服务端首先通过accept()获取到客户端的Socket,然后通过客户端的Socket获取到的流进行通信,这也使得服务端能够区分各个客户端。

文件传输示例

流程:客户端上传文件到服务器。服务器收到文件后保存该文件。保存成功后,向客户端发送响应。

客户代码

public class TCPUploadClient { public static void main(String[] args) throws IOException { //1.创建TCP客户端Socket服务Socket client=new Socket(); //2.连接服务器InetSocketAddress 地址=new InetSocketAddress( ‘192.168.31.137’,10001);客户端.connect(地址); //3.读取客户端文件FileInputStream fis=new FileInputStream(‘E://girl.jpg’); //4.获取输出流OutputStream outputStream=client.getOutputStream(); //5.将文件写入服务器byte[] bytes=new byte[1024]; int len=0; while ((len=fis.read(bytes))!=-1 ){ outputStream.write(bytes,0,len); } //6.通知服务器数据写入完成client.shutdownOutput(); //7.读取服务器响应的数据InputStream inputStream=client.getInputStream(); BufferedReader br=new BufferedReader(new InputStreamReader(inputStream));字符串行=br.readLine(); System.out.println(行); //8.关闭流inputStream.close(); fis.close();客户端.close(); }}创建Socket并连接,读取本地文件输入流,将文件写入服务器,写入成功后读取服务器返回的数据。

服务器代码

public class TCPUploadServer { public static void main(String[] args) throws IOException { //1.创建客户端Socket ServerSocket serverSocket=new ServerSocket(10001); //2.获取客户端Socket Socket socket=serverSocket.accept( ); //3.通过客户端Socket获取输入流InputStream=socket.getInputStream(); //4.将流以文件的形式写入磁盘File dir=new File(‘F://tcp’) ; //如果文件夹不存在,则创建文件夹if(!dir.exists()){ dir.mkdirs();文件file=new File(dir,’girl.jpg’); FileOutputStream fos=new FileOutputStream( 文件); byte[] 字节=新字节[1024]; int len=0; while ((len=is.read(bytes))!=-1){ fos.write(bytes,0,len); }//5。通知客户端文件已保存OutputStream os=socket.getOutputStream(); os.write(‘成功’.getBytes()); //6.关闭流fos.close(); os.close();套接字.close(); }}创建Socket并获取客户端Socket和输入流,在F盘tcp目录下创建文件,将从客户端读取到的数据输出到文件中,成功保存到客户端。返回“成功”

这样我们就实现了亿个客户端上传文件的功能,比较简单。希望大家能够按照代码再敲一遍。

TCP Socket多线程应用

细心的同学可能发现了,在我们上面的例子中,一台服务器只能接收一个客户端的一个请求,这显然是不现实的。那么一台服务器如何同时服务多个客户端呢?然后写代码

//客户端1 public class TCPClient1 { public static void main(String[] args) throws IOException { System.out.println(‘TCPClient1 Start.’); //1.创建TCP客户端Socket服务Socket client=new Socket(); //2.连接到服务器InetSocketAddress 地址=new InetSocketAddress(‘192.168.31.137’,10004);客户端.connect(地址); //3.连接成功后获取客户端Socket输出流OutputStream outputStream。=client.getOutputStream(); //4.通过输出流向服务器写入数据outputStream.write(‘Hello my name is Client1’.getBytes()); //5.告诉服务器它已完成发送client.shutdownOutput( ); //6.读取服务器返回的数据InputStream=client.getInputStream(); byte[] 字节=新字节[1024]; int len=is.read(bytes); System.out.println(new String(字节,0,len)); //7.关闭流client.close(); }}//客户端2 public class TCPClient2 { public static void main(String[] args) throws IOException { System.out.println( ‘TCPClient2 Start.’); //1.创建TCP客户端Socket服务Socket client=new Socket(); //2.与服务器连接InetSocketAddress address=new InetSocketAddress(‘192.168.31.137’,10004) ;客户端.connect(地址); //3.连接成功后,获取客户端Socket输出流OutputStream outputStream=client.getOutputStream(); //4.通过输出流向服务器写入数据outputStream.write(‘Hello my name is Client2’.getBytes()); //5.告诉服务器已经发送完毕client.shutdownOutput(); //6.读取服务器返回的数据InputStream=client.getInputStream(); byte[] 字节=新字节[1024]; int len=is.read(bytes); System.out.println(new String(bytes,0,len)); //7.关闭流client.close(); }}//服务器public class TCPServer { public static void main(String[] args) throws IOException { receive(); } private static void receive() throws IOException { System.out.println(‘服务器启动.’); //创建服务Terminal Socket并指定端口号ServerSocket serverSocket=new ServerSocket(10004); while (true){ //获取客户端的Socket Socket socket=serverSocket.accept(); //通过客户端的Socket获取输入流InputStream is=socket .getInputStream(); //获取客户端通过输入流传入的数据byte[] bytes=new byte[1024]; int len=is.read(bytes); System.out.println(new String(bytes,0,len)); //将客户端发送的数据原样返回到OutputStream os=socket.getOutputStream(); os.write(new String(bytes,0,len).getBytes()); //关闭连接socket.close(); } }}客户端1 控制台

TCPClient1 开始.您好,我的名字是Client1 客户端2 控制台

TCPClient2 Start.你好我叫Client2 这样一台服务器就可以服务多个客户端

细心的同学可能发现了,上面的写法有问题。由于服务器始终在主线程中处理请求,因此客户端的请求需要由服务器排队。例如:Client1向服务器执行请求。请求,服务器在响应Client1之前不会接受其他请求。显然这是不合逻辑的。真正的服务器必须能够并发处理。多线程可以解决这个问题。我们来看看修改后的服务器代码。

公共类TCPServer { 公共静态void main(String[] args) 抛出IOException { receive(); } } private static void receive() throws IOException { System.out.println(‘服务器启动.’); //创建服务Terminal Socket并指定端口号ServerSocket serverSocket=new ServerSocket(10004); while (true){ //获取客户端的Socket Final Socket socket=serverSocket.accept(); //通过线程执行客户端请求new Thread(new Runnable () { @Override public void run() { try { //通过客户端的Socket获取输入流InputStream is=socket.getInputStream(); //获取客户端通过输入流传递的数据byte[] bytes=new byte[1024]; System.out.println(new String(bytes,0,len)); /将客户端发送的数据原样返回给OutputStream os=getOutputStream(); os.write(new String(bytes,0,len).getBytes()); //关闭连接socket.close(); catch (IOException e) { e.printStackTrace() } } }) .start(); } }} 运行效果和添加线程之前一样,但是这种方法效率更高。

用户评论

我听说你还不知道如何进行Socket 编程
。婞褔vīp

太扎心了!我也一直没想学习 Socket 编程,总感觉好难啊… 但是现在看到这个主题,好像应该开始接触一下了,毕竟在未来工作中肯定要用上吧。<br>

    有17位网友表示赞同!

我听说你还不知道如何进行Socket 编程
鹿先森,教魔方

哈哈,我就知道不是我一个人还没学会Socket编程呢。我一直觉得它看起来太复杂了,不知道从哪里开始下手比较好。这篇文章让我更加好奇这种技术背后的原理了。

    有13位网友表示赞同!

我听说你还不知道如何进行Socket 编程
心亡则人忘

这篇文章说的很清楚!之前我也感觉 Socket 编程非常深奥,看了这篇博文后,才明白它的实际应用场景和基本流程。有启发!

    有18位网友表示赞同!

我听说你还不知道如何进行Socket 编程
灵魂摆渡人

Socket 编程确实挺重要的,很多高大上的网络项目都离不开它。虽然我现在的代码还没接触到 Socket,但为了将来积累经验,我会尽量去深入学习它!

    有14位网友表示赞同!

我听说你还不知道如何进行Socket 编程
留我一人

说来惭愧,我到现在还是不会 Socket 编程啊,只听过别人提起。这篇文章帮我打开了思路,以后有机会一定要好好学习一下,感谢分享!

    有14位网友表示赞同!

我听说你还不知道如何进行Socket 编程
顶个蘑菇闯天下i

其实 Socket 编程的难点在于理解其底层的网络原理,建议先学习 TCP/IP 网络模型,再学习 Socket 编程会更容易上手。 这篇博文也帮助我理清了一些模糊的概念.

    有17位网友表示赞同!

我听说你还不知道如何进行Socket 编程
百合的盛世恋

虽然我没有学过 Socket 编程,但我感觉这个技术很实用,希望能有机会学习一下。希望作者能分享更多具体的案例和代码实例,这样对理解 Socket 编程会更有帮助。

    有7位网友表示赞同!

我听说你还不知道如何进行Socket 编程
夏日倾情

这篇文章写的太基础了,我期望看到更深入的讲解,比如不同类型 Socket 的应用场景,以及常见的 Socket 错误处理机制等等,毕竟对于有一定基础的程序员来说,这些都是非常有用的知识。

    有8位网友表示赞同!

我听说你还不知道如何进行Socket 编程
Hello爱情风

学习技术确实需要不断地尝试和实践,如果一直停留在阅读博客文章阶段就很难有所突破。下次我再学习 Socket 编程的时候,一定会认真编写代码来加深理解!

    有7位网友表示赞同!

我听说你还不知道如何进行Socket 编程
在哪跌倒こ就在哪躺下

这篇博文的缺点就是例子太简单了,应用场景没有展开细述。我觉得对于想要深入了解 Socket 编程的人来说,需要更多的实战案例和分析,才能更好地掌握该技术的精髓。

    有12位网友表示赞同!

我听说你还不知道如何进行Socket 编程
哥帅但不是蟋蟀

Socket 编程确实有它的难度,尤其是跨平台的开发,需要注意很多细节…感觉还是得自己动手实践才能真正明白!

    有16位网友表示赞同!

我听说你还不知道如何进行Socket 编程
柠栀

这篇文章让我对 Socket 编程有了更系统的认识!之前一直觉得它很复杂,现在看来只要掌握了基本原理就可以逐步学习。我会尝试用 Python 来实现几个简单的 Socket 程序,看看实际应用效果如何。

    有17位网友表示赞同!

我听说你还不知道如何进行Socket 编程
夏以乔木

作者你说的太对了!学会 Socket 编程确实可以让我们更好地理解网络编程的精髓。我已经迫不及待想去实践一下了,希望能开发一个简单的小服务程序试试运气!🤞

    有16位网友表示赞同!

我听说你还不知道如何进行Socket 编程
昂贵的背影

我感觉文章写得很浅显,对于已经有一定的编程基础的人来说并没有太多参考价值。希望作者能针对更高级的 Socket 编程技巧进行讲解,例如网络安全、高性能编程等。

    有6位网友表示赞同!

我听说你还不知道如何进行Socket 编程
逾期不候

Socket 编程的确是个好学难精的技术,需要仔细学习和实践才能真正掌握。这篇博文算是打开思路的第一步,接下来还需要多看文档和实例代码来加深理解。

    有13位网友表示赞同!

我听说你还不知道如何进行Socket 编程
伪心

我个人觉得这篇文章的写作风格有点过于平淡,缺乏一些生动的例子和图示解释。如果能增加一些趣味性元素,会更加吸引读者阅读和学习!

    有20位网友表示赞同!

原创文章,作者:小su,如若转载,请注明出处:https://www.sudun.com/ask/116451.html

(0)
小su's avatar小su
上一篇 2024年9月1日 上午6:36
下一篇 2024年9月1日 上午6:45

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注