天籁轿车socket是干嘛用的
socket是Java网络编程的一种,以下是它的解释:
所谓socket通常也称作"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求。以J2SDK-13为例,Socket和ServerSocket类库位于java net包中。ServerSocket用于服务器端,Socket是建立网络连接时使用的。在连接成功时,应用程序两端都会产生一个Socket实例,操作这个实例,完成所需的会话。对于一个网络连接来说,套接字是平等的,并没有差别,不因为在服务器端或在客户端而产生不同级别。不管是Socket还是ServerSocket它们的工作都是通过SocketImpl类及其子类完成的。
搭建外网访问,首先你要有一台外网可访问的服务器,有以下几种方法可以实现。
一、购买外网服务器。由于服务器端使用JAVA语言开发,所以外网服务器操作系统可以是Linux或Windows,这个需要你花钱购买。如果只是测试,你可以选择购买阿里云的云服务器,非常便宜。
二、还有一种方法就是你通过花生壳之类的软件进行映射你的网络,但花生壳对长城宽带之类的网络支持不是特别好,如果需要很好的支持,那也需要花钱购买。
三、如果你是通过路由器上网,并且可以操作路由器权限且使用的是电信或者是联通的网络,那可以直接在路由器里面做端口映射,这个你可以百度一下,有很多文章讲的非常清楚,这里篇幅限制,就不贴了。
四、如果你是直接通过猫上网且使用电信或联通宽带,那可以直接使用本机外网IP访问你的程序。
以上四种方法中,最稳定的还是购买外网服务器,其它都会有各种问题,你可以选择其中适合你的一种方法。希望能帮助到你
1可能是在获取客户端的ip和端口时,处理出现问题,导致无法正确发送到客户端。
2客户端是否使用固定的端口来接收服务器信息,或服务器是否正确发送到客户端的相应的端口。
3通过上面分析,最大可能是在处理端口出现问题,请重新检查。
4实在不行,最好使用抛出异常方法来捕获错误消息,或是通过一步一步调试分析数据发送过程。
1、客户端连接一般是与用户绑定的,无用户数据的socket就算能区分连接也毫无意义。一般做法是客户端利用HTTP登录,登录服务器分析各个socket服务器的负载后发送给客户端应该连接哪个socket服务器,客户端拿到登录成功后的用户ID后再连接socket服务器,此用户ID就可以用于socket服务器区分客户端连接。
2、如果自建socket服务器,建议最好不用SSH、SSM之类的框架,可控性更高,更加轻量,但工作量稍显繁多,且复杂;建议使用Netty做scoket基础框架。
3、客户端服务端通信可以用json格式的文本行(字符流,以\r\n自动做粘包断包解码),还有自定义数据格式的字节流(比如 数据包内容长度+数据包内容,以数据包内容长度手动编写代码做粘包断包解码),还可以用时下流行的protobuf。
我们定义发送者和接收者,发送者作为客户端,接收者作为服务端。
Senderjava
import javaioDataOutputStream;
import javaioIOException;
import javanetSocket;
import javautilArrays;
public class Sender {
public static void main(String[] args) throws Exception {
// 127001 代表本机地址,在 8888 端口上监听
Sender sender = new Sender("127001", 8888);
byte[] bytes = {15, 16, 17, 120}; // 对应的十六进制是 0F 10 11 78
sendersend(bytes);
Systemoutprintln("发送" + ArraystoString(bytes) + "完毕!");
}
private final String host;
private final int port;
public Sender(String host, int port) {
thishost = host;
thisport = port;
}
private void send(byte[] bytes) throws IOException {
Socket socket = new Socket(host, port); // 建立和服务端的 socket
try (DataOutputStream dos // 建立输出流
= new DataOutputStream(socketgetOutputStream())) {
doswrite(bytes, 0, byteslength); // 向输出流写入 bytes
}
}
}
Receiverjava
import javaioDataInputStream;
import javaioIOException;
import javanetServerSocket;
import javanetSocket;
public class Receiver {
public static void main(String[] args) throws Exception {
Receiver receiver = new Receiver(8888);
receiverreceive();
}
private final ServerSocket serverSocket;
public Receiver(int port) throws IOException {
serverSocket = new ServerSocket(port);
}
private void receive() throws IOException {
Systemoutprintln("等待客户端连接");
Socket socket = serverSocketaccept();
try (DataInputStream dis = new DataInputStream(socketgetInputStream())) {
byte[] bytes = new byte[1024]; // 假设发送的字节数不超过 1024 个
int size = disread(bytes); // size 是读取到的字节数
String hex = bytesToHex(bytes, 0, size);
Systemoutprintln("接收到的byte数组的十六进制:" + hex);
}
}
/
将 byte 数组转化为十六进制字符串
@param bytes byte[] 数组
@param begin 起始位置
@param end 结束位置
@return byte 数组的十六进制字符串表示
/
private String bytesToHex(byte[] bytes, int begin, int end) {
StringBuilder hexBuilder = new StringBuilder(2 (end - begin));
for (int i = begin; i < end; i++) {
hexBuilderappend(CharacterforDigit((bytes[i] & 0xF0) >> 4, 16)); // 转化高四位
hexBuilderappend(CharacterforDigit((bytes[i] & 0x0F), 16)); // 转化低四位
hexBuilderappend(' '); // 加一个空格将每个字节分隔开
}
return hexBuildertoString()toUpperCase();
}
}
运行,首先启动服务端:
然后启动客户端:
查看接收结果:
在客户端退出之后,会出现socket连接中断,此时是会抛出异常,在抛出异常时打印中断的客户端即可。
1 while(Binputread()!= -1) 这种方法能判断出客户端输入是否为空,客户端断开能跳出死循环,但是得到的数据却从第二个开始了,所以这方法不适宜。
2 在死循环中加入以下代码:
try {
socketsendUrgentData(0);
} catch (IOException e) {
done= false; //如果抛出了异常,那么就是断开连接了 跳出无限循环
}
套接字(Socket),就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。
一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制。从所处的地位来讲,套接字上联应用进程,下联网络协议栈,是应用程序通过网络协议进行通信的接口,是应用程序与网络协议根进行交互的接口。
套接字是通信的基石,是支持TCP/IP协议的路通信的基本操作单元。
可以将套接字看作不同主机间的进程进行双间通信的端点,它构成了单个主机内及整个网络间的编程界面。套接字存在于通信域中,通信域是为了处理一般的线程通过套接字通信而引进的一种抽象概念。
套接字通常和同一个域中的套接字交换数据(数据交换也可能穿越域的界限,但这时一定要执行某种解释程序),各种进程使用这个相同的域互相之间用Internet协议簇来进行通信。
Socket(套接字)可以看成是两个网络应用程序进行通信时,各自通信连接中的端点,这是一个逻辑上的概念。它是网络环境中进程间通信的API(应用程序编程接口),也是可以被命名和寻址的通信端点,使用中的每一个套接字都有其类型和一个与之相连进程。
通信时其中一个网络应用程序将要传输的一段信息写入它所在主机的 Socket中,该 Socket通过与网络接口卡(NIC)相连的传输介质将这段信息送到另外一台主机的 Socket中,使对方能够接收到这段信息。
Socket是由IP地址和端口结合的,提供向应用层进程传送数据包的机制。
类型
1、数据报套接字
无连接套接字,使用用户数据报协议(UDP)。在数据报套接字上发送或接收的每个数据包都单独寻址和路由。数据报套接字不能保证顺序和可靠性,因此从一台机器或进程发送到另一台机器或进程的多个数据包可能以任何顺序到达或可能根本不到达。在数据报套接字上发送广播可能需要特殊配置。
为了接收广播数据包,数据报套接字不应该绑定到特定地址,尽管在某些实现中,当数据报套接字绑定到特定地址时也可能接收广播数据包。
2、流套接字
面向连接的套接字,使用传输控制协议(TCP)、流控制传输协议(SCTP) 或数据报拥塞控制协议(DCCP)。流套接字提供了无记录边界的有序且独特的无错误数据流,并具有用于创建和销毁连接以及报告错误的明确定义的机制。
流套接字以带外功能可靠地、有序地传输数据。在 Internet 上,流套接字通常使用 TCP 实现,以便应用程序可以使用 TCP/IP 协议在任何网络上运行。
3、原始套接字
允许直接发送和接收 IP 数据包,无需任何特定于协议的传输层格式。对于其他类型的套接字,根据选择的传输层协议(例如 TCP、UDP)自动封装有效载荷,并且套接字用户不知道与有效载荷一起广播的协议头的存在。从原始套接字读取时,通常包含标头。
从原始套接字传输数据包时,自动添加标头是可选的。
大多数套接字应用程序编程接口(API),例如基于Berkeley 套接字的那些,支持原始套接字。Windows XP于 2001 年发布,在Winsock接口中实现了原始套接字支持,但三年后,微软出于安全考虑限制了 Winsock 的原始套接字支持。
原始套接字用于与安全相关的应用程序,如Nmap。原始套接字的一个用例是在用户空间中实现新的传输层协议。
原始套接字通常在网络设备中可用,用于路由协议,例如Internet 组管理协议(IGMP) 和开放最短路径优先(OSPF),以及用于Internet 控制消息协议(ICMP) 等事情,由ping 实用程序。
以上内容参考 -套接字
你的文件中的问题
// 会阻塞进程,直到有客户端连接上来为止
// 既然是直到有客户端连接上,那么就要弄明白哪个是与客户端连接的套接字
// sockClient就是与客户端连接的套接字
sockClient = accept(sockServer, (SOCKADDR)&addrClient, &len);
//接收并打印客户端数据
recv(sockClient, recvBuf, 100, 0);
printf("%s\n", recvBuf);
// 所以此处,应该把sockServer改为sockClient
send(/sockServer/sockClient, sendBuf, 100, 0);
PS:服务器客户端通信,是要保持服务器与客户端的连接。
而不能这样立即关闭,如果设置不对,立即关闭,缓冲区的数据是会丢失的。那客户端也就不会再收到数据了。
你可以加Sleep(10000);来测是通信过程
//关闭socket
closesocket(sockClient);
0条评论