标签:util 函数 资源 stc domain cli 描述 客户端连接 unknown
一、socket通讯过程
1、socket与socket编程简介:
socket 被翻译为“套接字”,它是计算机之间进行通信的一种约定或一种方式。通过 socket 这种约定,一台计算机可以接收其他计算机的数据,也可以向其他计算机发送数据。
我们所说的socket 编程,是站在传输层的基础上,所以可以使用 TCP/UDP 协议,但是不能进行访问网页,因为访问网页所需要的 http 协议位于应用层。作为一个应用程序是能实现该层以下的内容,而不能实现在该层之上的内容。
2、socket通讯过程:
(1)创建ServerSocket和Socket
(2)打开连接到Socket的输入/输出流
(3)按照协议对Socket进行读/写操作
(4)关闭输入输出流、关闭Socket

2、linux中的socket与windows中socket文件之间的区别。
socket作为套接字,能够对数据进行包装后进行发送,socket本质是一个文件。
Linux中是将socket文件视为普通文件,而在windows中将socket文件看成是一个网络连接来对待,因此需要调用专门针对 socket 而设计的数据传输函数。
二、基于java的socket编程
客户端与服务端的使用在控制台的使用代码如下所示。基于java 的Socket编程实践主要调用了java的Socket和ServerSocketAPI,针对服务端需要绑定ServerSocket类,接口绑定后进行监听accept方法,而针对客户端,绑定接口之后采用发送数据的方式。
1、客户端通讯过程
(1)创建Socket对象,指明需要连接的服务器的地址和端口号
(2)连接建立后,通过输出流想服务器端发送请求信息
(3)通过输入流获取服务器响应的信息
(4)关闭响应资源 ???????
import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
public class Client{
public static void testClient(){
System.out.println("正在向服务器请求连接。。。");
Socket socket = null;
Scanner keybordscanner = null;
Scanner inScanner = null;
PrintWriter pwtoserver = null;
try {
//使用的是InetAddress类获取连接到所有Socket编程的
socket = new Socket(InetAddress.getLocalHost(),6668);
inScanner = new Scanner(socket.getInputStream());
System.out.println(inScanner.nextLine());
pwtoserver = new PrintWriter(socket.getOutputStream());
System.out.print("我(客户端):");
keybordscanner = new Scanner(System.in);
while(keybordscanner.hasNextLine()){
String keyborddata = keybordscanner.nextLine();
//客户端发送的消息
System.out.println("我(客户端):"+keyborddata);
//写到服务端的的控制台
pwtoserver.println(keyborddata);
pwtoserver.flush();
//阻塞等待接收服务端的消息
String indata = inScanner.nextLine();
System.out.println("服务端:"+indata);
System.out.print("我(客户端):");
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
keybordscanner.close();
pwtoserver.close();
inScanner.close();
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
testClient();
}
}
2、服务端:
(1)创建ServerSocket对象,绑定监听端口
(2)通过accept()方法监听客户端请求
(3)连接建立后,通过输入流读取客户端发送的请求信息
(4)通过输出流向客户端发送乡音信息
(5)关闭相关资源
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class Server{
//服务器
public static void testServer(){
//创建一个服务器
System.out.println("等待客户端连接。。。");
PrintWriter pwtoclien = null;
Scanner keybordscanner = null;
Scanner inScanner = null;
ServerSocket ss = null;
try {
ss = new ServerSocket(6667);
//创建一个接收连接客户端的对象
Socket socket = ss.accept();
System.out.println(socket.getInetAddress()+"已成功连接到此台服务器上。");
//字符输出流
pwtoclien = new PrintWriter(socket.getOutputStream());
pwtoclien.println("已成功连接到远程服务器!"+"\t"+"请您先发言。");
pwtoclien.flush();
keybordscanner = new Scanner(System.in);
inScanner = new Scanner(socket.getInputStream());
//阻塞等待客户端发送消息过来
while(inScanner.hasNextLine()){
String indata = inScanner.nextLine();
System.out.println("客户端:"+indata);
System.out.print("我(服务端):");
String keyborddata = keybordscanner.nextLine();
System.out.println("我(服务端):"+keyborddata);
pwtoclien.println(keyborddata);
pwtoclien.flush();
}
socket.shutdownInput();
socket.shutdownOutput();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
pwtoclien.close();
keybordscanner.close();
inScanner.close();
try {
ss.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
testServer();
}
}
这里采用的是单线程通讯。并且采用了阻塞printWriter.flush的方式控制通讯的顺序:客户端发送消息之后服务端才能回复消息,只有当服务端对客户端进行回应客户端才能再次发送消息,当双方都不进行发送文件时形成了死锁,只有发送文件之后才能解除死锁。
服务端的控制台程序如图所示,使用的是InetAddress类进行获取发送文件的Address。除此之外,编写程序过程中,在两个类中容易弄混淆的是GetInputSream与GetOutputStream,前者是用来读,后者是用来写的。

客户端:客户端在控制台的显示如下所示。

在linux中观察java函数服务端调用的情况
使用的是strace 命令对调用进行追踪


三、linux中网络接口简介
linux中建立连接
站在更贴近系统的层级去看,两个机器间的通信方式,无非是要通过运输层的TCP/UDP,网络层IP,因此socket本质是编程接口(API),对TCP/UDP/IP的封装,TCP/UDP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口。
Socket的创建:
int socket (int domain, int type, int protocol);
创建一个服务器端的socket
int server_sockfd = socket(AF_INET, SOCK_STREAM, 0);
我们套接字已经创建好了,地址结构也已经了解了,接下来就是要将套接字和地址进行关联,关联的方法则是通过bind函数。
int bind(int sockfd, const struct sockaddr *addr, socklen_t len);
我们的socket已经创建出来了,当我们不再使用的时候,我们可以调用close函数来将其关闭,释放该文件描述符,这样便可以得到重新的使用。
套接字通信是双向的,但是,我们可以采用shutdown函数来禁止一个套接字的I/O
进行连接 #include <sys/socket.h>int connect(int sockfd, const struct sockaddr *addr, socklen_t len); 关闭连接 int shutdown(int sockfd, int how);
标签:util 函数 资源 stc domain cli 描述 客户端连接 unknown
原文地址:https://www.cnblogs.com/yyl666/p/11982190.html