-
Socket网络编程
2021-03-22 13:34:47Socket 1 环境查看 通过cmd窗口的命令:ipconfig查看本机IP地址 查看网络情况是否正常:ping百度官网 用来进行本地测试的地址 127.0.0.1,回环测试地址,默认代表的就是本机的IP ...Socket就是为网络编程提供的一Socket
1 环境查看
- 通过cmd窗口的命令:ipconfig查看本机IP地址
- 查看网络情况是否正常:ping百度官网
用来进行本地测试的地址 127.0.0.1,回环测试地址,默认代表的就是本机的IP
2 Socket概述
socket编程也叫套接字编程,应用程序可以通过它发送或者接受数据,可对其像打开文件一样打开/关闭/读写等操作. 套接字允许应用程序将I/O插入到网络中,并与网络中的其他应用程序进行通信. 网络套接字是IP地址与端口号TCP协议的组合 Socket就是为网络编程提供的一种机制,通信的两端都有Socket 网络通信其实就是Socket之间的通信,数据在两个Socket之间通过I/O进行传输.
3 服务器端
3.1 ServerSocket
在服务器端选择一个端口号,在指定端口上等待客户端发起连接
构造方法:
ServerSocket(int port) 创建绑定到特定端口的服务器套接字
常用方法:
Socket accept() 侦听并接收到此套接字的连接
void close() 关闭此套接字
启动服务:
ServerSocket ss = new ServerSocket(端口号);
等待客户端发起连接,连接后会建立起通道:Socket socket = ss.accept();4 客户端Socket
我们经常使用的就是客户端
构造方法:
Socket(String host,int port) 创建一个流套接字,并将其连接到指定主机上的指定端口号
常用方法:
InputStream getInputStream() 返回此套接字的输入流
OutputStream getOutputStream() 返回此套接字的输出流
void close() 关闭此套接字
新建Socket对象,连接指定IP指定的端口
Socket s = new Socket(IP,port);
从Socket获取双向的流:
InputStream in = s.getInputStream();
OutputStream out = s.getOutputStream();5 入门案例
5.1服务器端代码编写
需求: 服务器端接收客户端发来的数据”hello”,并且给客户端响应数据”world”
创建包: cn.tedu.net
创建类: Server.javapackage cn.tedu.net; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; /**本类用来表示Socket网络编程案例的服务器端 * 完成步骤分析: * 1.启动服务器 * 2.接收客户端的连接请求 * 3.接收客户端发来的数据 * */ /**测试注意事项:先启动服务器端,再启动客户端*/ public class Server { public static void main(String[] args) throws Exception { //1.启动服务器,指定端口号为8888,等待客户端的连接 /**注意: * 1.使用ServerSocket需要导包java.net.ServerSocket * 2.此操作会抛出异常 * 3.指定的端口号范围是:0-655535,而0-1024是系统端口号,不能指定 * */ ServerSocket ss = new ServerSocket(8888); //2.接收客户端的连接请求,并建立数据通信通道 Socket socket = ss.accept(); //3.获取到读取流,接收并读取客户端发来的数据 InputStream in = socket.getInputStream(); //通过循环挨个读取显示读到的内容 for(int i = 0;i < 5;i++) { //int b = in.read();//此方法读取的结果是把字符转成数字 char c = (char) in.read();//为了直接显示读取到的字符,需要强制类型转换(大转小,int转char) System.out.print(c);//print()同行输出,注意细节哦 } //5.给客户端发送数据 OutputStream out = socket.getOutputStream(); out.write("world".getBytes()); out.flush(); //4.释放资源 /**注意关流的顺序,后出现的先关闭*/ in.close(); ss.close(); } }
5.2 客户端代码编写
创建包: cn.tedu.net
创建类: Client.javapackage cn.tedu.net; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; /**本类用来表示Socket网络编程案例的客户端 * 完成步骤分析: * 1.指定要连接的服务器 * 2.给服务器发送hello * */ public class Client { public static void main(String[] args) throws Exception { //1.指定要连接的服务器,需要同时指定服务器的IP & Port /**注意: * 1.使用Socket需要导包java.net.Socket * 2.此操作会抛出异常 * 3.如果使用的是本机的IP,地址是固定值,用来测试时使用127.0.0.1 * */ Socket socket = new Socket("127.0.0.1",8888); //2.给服务器端发送hello OutputStream out = socket.getOutputStream(); //把要输出的数据hello字符串转变成byte[]的形式进行输出 out.write("hello".getBytes()); out.flush(); //4.读取从服务器端返回的数据 InputStream in = socket.getInputStream(); for (int i = 0; i < 5; i++) { char c = (char) in.read();//为了显示字符而不是数字,强制类型转换成char System.out.print(c);//不换行展示获取到的数据 } //3.释放资源 //out.close(); socket.close(); } }
5.3 测试注意事项:
1.测试顺序:先启动服务器端,再启动客户端
2.可以打开多个控制台显示窗口,方便查看
3.可以将其中一个控制台显示窗口固定,否则多个窗口的显示内容是一样的
4.注意每次测试完毕后,都需要将之前的控制台窗口都关闭后再次进行新一轮的测试
注意:要先启动服务器端再启动客户端,否则会报错,如下所示:
注意,下次测试的时候,把上次测试的窗口都关掉,重复启动多次,正在使用,新次测试就无法使用
6 服务器端线程模型
入门案例中,存在两种阻塞状态:
- 服务器端的accept()一直在等待客户端的连接
- 通信中的read()死等数据
7 读一行写一行案例
创建包: cn.tedu.net
创建类: TestIO.javapackage cn.tedu.net; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; /**这个类用来测试一行一行读取,一行一行写出*/ public class TestIO { public static void main(String[] args) { //method();//初步测试readLine() method2();//改进 } public static void method2() { BufferedReader in = null; PrintWriter out = null; try { //1.读取一行数据,先拿到读取数据的流,注意文件需要自己在win创建 in = new BufferedReader(new FileReader("D:\\b.txt")); //2.定义变量,记录每行读取到的数据 String line; //3.设置循环读取数据,只要有数据就一直读取 while( (line=in.readLine()) != null) { System.out.println(line); } //4.一行行写出数据:PrintWriter out = new PrintWriter(new FileWriter("D:\\b.txt")); out.println("java"); out.println("hello"); out.flush();//为了防止有数据没有发送过去,可以刷一下 } catch (Exception e) { e.printStackTrace(); }finally { try { //5.释放资源 out.close(); in.close(); } catch (IOException e) { e.printStackTrace(); } } } public static void method() { try { //1.读取一行数据,先拿到读取数据的流,注意文件需要自己在win创建 BufferedReader in = new BufferedReader(new FileReader("D:\\b.txt")); //2.调用readLine方法进行测试 String line = in.readLine(); String line2 = in.readLine(); String line3 = in.readLine(); //测试1:b.txt没有数据时,readLine()返回null //测试2:b.txt有数据,而且是1整行数据,readLine()可以返回整行全部数据 //测试3:b.txt有数据,而且是多行数据,readLine()只可以返回第1行全部数据 /**原因:readLine()在读取数据时,会读取特殊标记,换行符\r\n,读到换行符就结束 * 结论:readLine()只可以读取1整行数据,如果是多行数据,需要多次调用 * */ //3.打印测试结果 System.out.println(line); System.out.println(line2); System.out.println(line3); } catch (Exception e) { e.printStackTrace(); } } }
8 拓展 : 回声案例
需求:接收客户端输入的每行数据,服务器再把回应给到用户
8.1 服务器端
接收客户端输入的每行数据,服务器再把回应给到用户
创建包: cn.tedu.net
创建类: Server2.javapackage cn.tedu.net; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.Scanner; /**这个类用来当做回声案例的服务器端 * 1.启动服务器 * 2.接收客户端的连接请求 * 3.给每个用户分配对应的话务员 * 4.话务员:主要负责和对应的客户端对象进行沟通I/O * */ /**1.创建优化后的Server2类,充当服务器端*/ public class Server2 { /**2.创建方法,负责服务多个客户*/ public void service() { /**3.匿名对象+匿名内部类(重写run方法)*/ new Thread() { /**5.把业务写在run()中*/ @Override public void run() { try { //5.1 启动服务器,设置端口号为8000并等待客户端连接 ServerSocket ss = new ServerSocket(8000); System.out.println("服务器启动成功!"); while(true) {//死循环,一直accept,也就是接受客户端的连接请求 //5.2 一直接受所有客户端的连接请求 Socket socket = ss.accept(); System.out.println("客户端连接成功!"); //5.3 给每个客户分配自己对应的话务员,1v1 HuaWuThread t = new HuaWuThread(socket); t.start(); } } catch (IOException e) { e.printStackTrace(); } }; }.start();/**4.启动线程*/ } /**6.创建话务员内部类,主要负责和客户端沟通 I/O*/ class HuaWuThread extends Thread{ //6.1 定义本类中的成员变量socket,用来保持通话 Socket socket; //6.2含参构造,接受当前的连接信息,保持通话,为谁服务就保存谁的数据 public HuaWuThread(Socket socket) { this.socket = socket; } //6.3把话务员的业务放在run(),一直读取客户端发来的数据,并作出回应 @Override public void run() { try { //7.1读取一行BufferedReader,并且写出一行PrintWriter --双向流 BufferedReader in = new BufferedReader( new InputStreamReader(socket.getInputStream())); PrintWriter out = new PrintWriter( new OutputStreamWriter(socket.getOutputStream())); //7.2读取客户端发来的一行数据 String line;//定义变量,记录读取到的一行数据 while((line = in.readLine()) != null) {//只要有数据就一直读 System.out.println("客户端发来的数据:"+line); //7.1可以给客户端作出响应-接收键盘输入的响应 System.out.println("请输入您的回应:"); String input = new Scanner(System.in).nextLine(); //7.2发出作为服务器的响应 out.println(input); out.flush();//把数据刷出去 } } catch (Exception e) { e.printStackTrace(); } } } public static void main(String[] args) { Server2 s = new Server2(); s.service(); } }
8.2 客户端
接收客户端输入的每行数据,服务器再把回应给到用户
创建包: cn.tedu.net
创建类:Client2.javapackage cn.tedu.net; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.Socket; import java.util.Scanner; /**本类用来做回声案例的客户端 * 1.连接指定的服务器 * 2.给服务器发送数据 * 3.接收服务器响应的数据 * */ public class Client2 { public static void main(String[] args) { try { //1.连接指定的服务器,同时指定服务器的IP和端口号 Socket socket = new Socket("127.0.0.1",8000); //2.给服务器发送数据 while(true) { //向服务器写出一行数据,并且读取服务器响应回来的数据 PrintWriter out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream())); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); //3.通过流对象进行发送和读取的操作 System.out.println("请输入您想给服务器发送的数据:"); String input = new Scanner(System.in).nextLine(); out.println(input);//向服务端发送指定数据 out.flush();//把数据刷出去 String line = in.readLine();//读取回声数据 System.out.println("服务器端响应的数据是:"+line); } } catch (Exception e) { e.printStackTrace(); } } }
- 通过cmd窗口的命令:ipconfig查看本机IP地址
-
socket网络编程
2019-02-18 17:28:18socket编程中,以下哪个socket的操作是不属于服务端操作的()? A.accept B.listen C.connect D.close 看答案解析很好的一张图,保留下来。 我想这个图配这个题一目了然吧,答案选C. TCP客户端: 1.建立连接套接字...今天做一道面试题,做错了。
socket编程中,以下哪个socket的操作是不属于服务端操作的()?
A.accept
B.listen
C.connect
D.close看答案解析很好的一张图,保留下来。
我想这个图配这个题一目了然吧,答案选C.TCP客户端:
1.建立连接套接字,设置Ip和端口监听,socket()
2.建立连接 connect
3.write() 获取网络流对象 发送数据
4.read()获取网络流对象 接收数据
5.关闭套接字TCP服务器端
1.建立端口监听 socket()
2.绑定指定端口 bind()
3.listen 进行端口监听
4.accept() 阻塞式 直到有客户端访问
5.read()获取客户端发送数据
6.write()发送返回数据
7.close关闭端口监听 -
Socket 网络编程
2015-06-02 11:07:121.TCP/IP、UDP TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制协议/网间协议,是一个工业... 网络编程学习笔记一:Socket编程: http://blog.csdn.net/gneveek/article/details/86991981.TCP/IP、UDP
TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制协议/网间协议,是一个工业标准的协议集,它是为广域网(WANs)设计的。
UDP(User Data Protocol,用户数据报协议)是与TCP相对应的协议。它是属于TCP/IP协议族中的一种。
下面这张图,表明了这些协议的关系,如图TCP/IP协议族包括运输层、网络层、链路层:2.Socket
在图1中,我们没有看到Socket的影子,那么它到底在哪里呢?还是用图来说话,一目了然。
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。
3.使用socket
前人已经给我们做了好多的事了,网络间的通信也就简单了许多,但毕竟还是有挺多工作要做的。以前听到Socket编程,觉得它是比较高深的编程知识,但是只要弄清Socket编程的工作原理,神秘的面纱也就揭开了。
一个生活中的场景。你要打电话给一个朋友,先拨号,朋友听到电话铃声后提起电话,这时你和你的朋友就建立起了连接,就可以讲话了。等交流结束,挂断电话结束此次交谈。生活中的场景就解释了这工作原理,也许TCP/IP协议族就是诞生于生活中,这也不一定。
4.代码示例
#import "ViewController.h" #import <sys/socket.h> #import <netinet/in.h> #import <arpa/inet.h> @interface ViewController () // 客户端 socket @property (nonatomic, assign) int clientSocket; @property (nonatomic, weak) IBOutlet UIWebView *myWebView; @end @implementation ViewController /** ======= 请求头 ======= 1> 请求行 GET / HTTP/1.1 GET 表示从服务器"拿"数据 / 访问服务器的根目录 HTTP/1.1 HTTP的协议以及版本 2> 请求头 Host: 要访问的主机 User-Agent: 用户代理,告诉服务器客户端的类型 Accept: 告诉服务器客户端支持的数据格式 Accept-Language: 告诉服务器客户端支持的语言 Accept-Encoding: 告诉服务器客户端支持的解压缩类型 HTTP请求本身的格式,是字符串格式的,最末一行,以 \n\n 结束,表示所有请求的内容发送完毕,服务器可以处理! 提示:key 值是 HTTP 协议定义的,不能随意更改! ==========响应 =========== 1> 状态行 HTTP/1.1 200 OK HTTP/1.1 HTTP的协议以及版本 200 状态码(404) 2XX 成功 4XX 客户端错误 5XX 服务器错误 2> 响应头,服务器告诉客户端的一些信息 提示:响应的信息,通常在开发“下载”功能时,才会使用,平时用不着 Date: 响应日期 Server: 服务器的信息 // 文件长度 Content-Length: 24 3> 数据实体,从服务器返回的二进制数据! println("hello world!"); */ - (void)viewDidLoad { [super viewDidLoad]; // http 端口是 80 if ([self connectToHost:@"61.135.169.125" port:80]) { NSLog(@"连接成功"); } // 发送消息给 web 服务器 // 建立请求字符串 NSString *request = @"GET / HTTP/1.1\n" "Host: www.baidu.com\n" "User-Agent: iPhone AppleWebKit\n\n"; // 对结果的处理 NSString *result = [self sendAndRecv:request]; // 找 \r\n 的出现的位置 NSRange range = [result rangeOfString:@"\r\n\r\n"]; // 判断是否找到 if (range.location == NSNotFound) { NSLog(@"html 错误"); return; } NSString *html = [result substringFromIndex:range.location]; [self.myWebView loadHTMLString:html baseURL:[NSURL URLWithString:@"http://www.baidu.com"]]; } - (BOOL)connectToHost:(NSString *)host port:(int)port { // 1. socket /** 参数 domain: 协议域,AF_INET type: Socket 类型,SOCK_STREAM(流 TCP)/SOCK_DGRAM(报文,提示: 在有些公司的程序员给服务器发送数据,会说:发送报文) protocol: IPPROTO_TCP,提示:如果输入0,会根据第二个参数,自动选择协议 返回值 socket 如果>0,就是正确的 */ self.clientSocket = socket(AF_INET, SOCK_STREAM, 0); // 2. 连接到另外一台计算机 /** 参数 1> 客户端socket 2> 指向数据结构sockaddr的指针,其中包括目的端口和IP地址 C 语言中没有对象,实现都是通过结构体来实现的 3> 结构体数据长度 返回值 0 成功/其他 错误代号,很多C语言的程序都会如此设计,原因:成功只有一个,失败会有很多种! C 语言中,通常是非零即真 */ struct sockaddr_in serverAddress; // 1> 地址 inet_addr 可以将 ip 地址转换成整数 // 提示:在网络上的使用的很多数据,需要做字节翻转 serverAddress.sin_addr.s_addr = inet_addr(host.UTF8String); // 2> 端口 htons 可以将端口转换成整数 // 端口号同样要做字节翻转 serverAddress.sin_port = htons(port); // 3> 协议 serverAddress.sin_family = AF_INET; // 在 C 语言中,通常传递结构体的指针同时,会传递结构体的尺寸 int result = connect(self.clientSocket, (const struct sockaddr *)&serverAddress, sizeof(serverAddress)); return (result == 0); } /** * 发送&接收消息 */ - (NSString *)sendAndRecv:(NSString *)msg { // 3. 发送数据给服务器 /** 参数 1> 客户端socket 2> 发送内容地址 3> 发送内容长度 4> 发送方式标志,一般为0 返回值 如果成功,则返回发送的字节数,失败则返回SOCKET_ERROR 提示:在很多C语言框架中,会将基本数据类型进行封装,使用的时候,便于后续框架的调整 */ // 在 UTF8 编码中,一个中文对应 3 个字节 ssize_t sendLen = send(self.clientSocket, msg.UTF8String, strlen(msg.UTF8String), 0); // 4. 从服务器接收数据 uint8_t buffer[1024]; // 1> 定义一个可变的二进制数据,方便拼劲 NSMutableData *dataM = [NSMutableData data]; // 服务器返回的回车计数 int count = 0; while (count == 0) { // 2> 接收数据 ssize_t recvLen = recv(self.clientSocket, buffer, sizeof(buffer), 0); [dataM appendBytes:buffer length:recvLen]; // 通过跟踪,\r\n\r\n 需要继续等待,\r\n 表示传输结束 // 取末尾一个字节 uint8_t lastByte = buffer[recvLen - 1]; // 取倒数第三个字节 uint8_t preLastByte = buffer[recvLen - 3]; if (lastByte == '\n' && preLastByte != '\n') { count++; } } return [[NSString alloc] initWithData:dataM encoding:NSUTF8StringEncoding]; } /** * 断开连接 */ - (void)disconnect { // 5. 关闭连接 close(self.clientSocket); } @end
5. 延伸阅读
1.Linux socket 编程:
http://www.ibm.com/developerworks/cn/education/linux/l-sock/l-sock.html
2. 网络编程学习笔记一:Socket编程:
http://blog.csdn.net/gneveek/article/details/8699198 -
Linux中socket 网络编程
2016-10-25 15:32:05 -
C++socket网络编程--http服务器(支持php)实战教学视频
2017-03-07 16:22:12本课程包含了socket网络编程常用的所有特性,包括tcp、udp协议的基础编程,广播包,超时连接,多路复用,高并发的epoll多路复用,多线程的服务端。课程讲解理论与实践相结合,实践以代码延时讲解为主。 -
Socket网络编程学习笔记
2019-08-02 17:15:48Socket网络编程 客户端与服务端 协议栈 protocol stack复杂的网络建立在简单网络服务的基础之上 应用层 用API获取一个JSON文档 import requests def geocode(address): parameter = {'address': address, '... -
Socket网络编程进阶与实战
2019-01-27 18:31:23Socket网络编程进阶与实战以保存到百度云 -
【网络编程】Socket网络编程基础
2019-06-12 21:41:50文章目录网络编程概述Socket与TCP UDPSocket TCP演示报文段协议Mac地址IP、端口、远程服务器IPv4IPv6端口远程服务器 网络编程概述 什么是网络编程 网络编程从大的方面说就是对信息的发送到接收 通过操作相应Api调度... -
Linux下Socket网络编程
2019-03-24 11:27:26在进行socket网络编程之前,我们需要知道socket是什么?在Unix/linux操作系统中有一个哲学思想,那就是万物皆文件,socket也不例外,它是可读、可写、可控制、可关闭的文件描述符。 #include <iostream> #... -
Python运维-Socket网络编程
2019-07-11 13:20:16慕课网上《Python运维-Socket网络编程》课程个人总结笔记,侵删。 慕课网视频链接:https://www.imooc.com/learn/1031 一、课程介绍 1.1 socket简介 Socket是什么? Socket是电脑网络中进程间数据流的端点 Socket是... -
MFC Socket网络编程之TCP客户端
2017-07-23 17:49:51MFC Socket网络编程客户端 -
C++ Socket网络编程
2016-03-17 10:02:00本来搜集到的一些 关于C++ 网络编程 Socket套接字的一些资源 -
十三.linux网络之Socket网络编程基础(TCP协议及socket编程接口)
2019-05-08 10:26:03文档:十三.linux网络之Socket网络编程基础(... 链接:http://note.youdao.com/noteshare?id=80df9f088e86efaa65539c40b23f5594&sub=E3F0055D389F4939ADB5DD022FB8B39A 一.linux网络编程框架 1、网络是分层... -
嵌入式 Linux网络编程(一)——Socket网络编程基础
2017-03-26 12:44:11嵌入式 Linux网络编程一——Socket网络编程基础一、Socket简介1、网络中进程间通信本机进程使用进程号区别不同的进程进程间通信方式有管道、信号、消息队列、共享内存、信号量等。网络中进程间的通信首先需要识别... -
socket网络编程基础小记
2015-07-13 21:06:45本文记录了socket网络编程的基础知识,主要内容如下:1、网络中进程之间如何通信?2、Socket是什么?3、socket的基本操作;4、socket中TCP的三次握手建立连接详解;5、socket中TCP的四次握手释放连接详解。