C# socket 多线程 客户端要点两次“发送”,服务端才能显示数据

C# socket 多线程 客户端要点两次“发送”,服务端才能显示数据,第1张

在监听过程中,接受一个用户就开启一个带有socket参数的新线程,找个参数记录socket和线程;

单击stop后将带有socket的线程和socket全部结束掉。

(监听也放在一个新线程中)

客服端:
package MyKeFudaun;
import javaioBufferedReader;
import javaioBufferedWriter;
import javaioIOException;
import javaioInputStreamReader;
import javaioOutputStreamWriter;
import javanetSocket;
import javanetUnknownHostException;
public class KeFuDuan {
public static void main(String[] args) {
KeFuDuan kf = new KeFuDuan();
kfstart();
}
public void start(){
Socket sco;
String ss= "";
try {
sco = new Socket("127001",8866);
KeFuduanJie kf = new KeFuduanJie(sco);
KeFuWuFasong kfs = new KeFuWuFasong(sco);
kfstart();
kfsstart();

//scoclose();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
eprintStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
eprintStackTrace();
}
}
}
class KeFuduanJie extends Thread{

Socket soc;
String ss;
BufferedReader br;
public KeFuduanJie(Socket soc){
try {
thissoc = soc;
br = new BufferedReader(new InputStreamReader(socgetInputStream()));

} catch (IOException e) {
eprintStackTrace();
}

}

//负责接受服务端来的信息
public void run(){
while(true){
//接受服务器端来的信息
try {
ss = brreadLine();
Systemoutprintln("服务器---->客服端: "+ss);
} catch (IOException e) {
// TODO Auto-generated catch block
eprintStackTrace();
}
}

}
}
//向服务器发送东西
class KeFuWuFasong extends Thread{

Socket soc;
BufferedWriter bw;
BufferedReader brr;
public KeFuWuFasong(Socket soc){

thissoc = soc;

try {
brr =new BufferedReader(new InputStreamReader(Systemin));
bw = new BufferedWriter(new OutputStreamWriter(socgetOutputStream()));
} catch (IOException e) {
// TODO Auto-generated catch block
eprintStackTrace();
}
}

public void run(){
while(true){
//向服务器发送请求
try {
bwwrite(brrreadLine());
bwnewLine();
bwflush();// 或者用bwclose()
} catch (IOException e) {
// TODO Auto-generated catch block
eprintStackTrace();
}
}
}
}
服务器端:
package MyKeFudaun;
import javaioBufferedReader;
import javaioBufferedWriter;
import javaioIOException;
import javaioInputStreamReader;
import javaioOutputStreamWriter;
import javanetServerSocket;
import javanetSocket;
public class Server {
public static void main(String[] args) {
Server server = new Server();
serverstart();
}

public void start(){

try { //服务器端打开端口
ServerSocket server = new ServerSocket(4499);
Socket socket = null;
ServerToClientThread stct = null;

while(true){
socket = serveraccept(); //迎接(接收)客户端的Socket访问
stct = new ServerToClientThread(socket); //分配一个新线程负责和信赖的Socket沟通
stctstart();
}

} catch (IOException e) {
eprintStackTrace();
}
}
}
package MyKeFudaun;
import javaioBufferedReader;
import javaioIOException;
import javaioInputStreamReader;
import javanetSocket;
public class ServerReceiveFromClient extends Thread{
Socket socket;
BufferedReader br;
String s;

public ServerReceiveFromClient(Socket socket){
thissocket = socket;
try {
br = new BufferedReader(new InputStreamReader(socketgetInputStream()));
} catch (IOException e) {
eprintStackTrace();
}
}

public void run(){

while(true){
try {
s = brreadLine();
Systemoutprintln(socketgetInetAddress()getHostAddress()+"发送了:"+s);

} catch (Exception e) {
eprintStackTrace();
}

}
}
}
package MyKeFudaun;
import javaioBufferedReader;
import javaioBufferedWriter;
import javaioIOException;
import javaioInputStreamReader;
import javaioOutputStreamWriter;
import javanetSocket;
public class ServerToClientThread extends Thread{
Socket socket;
BufferedReader br;
BufferedWriter bw;
String s;

//建立的同时,和客户端的Socket建立输入、输出流
public ServerToClientThread(Socket socket){
thissocket = socket;
try {
bw = new BufferedWriter(new OutputStreamWriter(socketgetOutputStream()));
} catch (IOException e) {
eprintStackTrace();
}

}

public void run(){
ServerReceiveFromClient srfc = new ServerReceiveFromClient(socket);
srfcstart();

while(true){
try {
bwwrite("欢迎光临。");
bwnewLine();
bwflush();
Threadsleep(101000);
} catch (IOException e) {
eprintStackTrace();
} catch (InterruptedException e) {
eprintStackTrace();
}
}
}
}

计算机网络相关的问题,如果想去了解,前提就是深刻理解网络4/7层模型。

记住并理解,上面每一层。切记,切记,切记。知道一些就可以开始主题,分两个部分TCP和Socket。

TCP是(Tranfer Control Protocol)的简称,在OSI参考模型第四层,也就是端口,到端口的的通信,它是一个可靠的双向连接,一旦建立连接就可以双向数据传输,双方都可以进行发送或接收 *** 作。

最常听说的就是三次握手。是的它说的就是TCP建立连接的过程。具体的步骤如下:

第一步:Server监听端口,状态为:Listen 

第二部:Client发送SNY包,请求连接,并将状态改为:SYN_SEND

第三部:Server发送ACK包,和SNY包,同意,并请求连接,状态改为:SYN_RCVD

第四部:Client发送ACK包,Server收到包后,连接建立。双方状态改为:ESTABLISHED

第一步:Client发起FIN包。状态变为:FNI_WAIT_1

第二步:Server发送ACK包。状态变为:CLOSE_WAIT,Client收包后状态变为:FNI_WAIT_2

第三步:Server发送FIN包,状态变为:LAST_ACK。Client收包后状态变为:TIME_WAIT

第四步:Client发送ACK包。双方状态变为:CLOSED 

需要注意的是,Client是在收到Server FIN包后两个最大报文时间(2MSL)后变为CLOSED状态的。双方都可以发起断开请求,上面是已先发起请求的是Client。

如何验证上面讲的这些呢?那就是抓包分析,其实日常的开发中也可以通过抓包来发现问题。在这里我简单贴个图看一下TCP的包,这个工具非常强大感兴趣的朋友可以去深入了解一下。

1可以在这个过滤,通过协议,通过IP,通过端口都可以。

2这个就是每个包,例子中的这个是个[SYN,ACK]包,就是建立TCP连接的第二次握手

3被抓取的包对应的网络层,从上到下分别是:物理层、数据链路层、网络层、传输层。

Socket其实就是TCP协议的实现。也就是说它就是TCP的API,当然其实Socket也支持别的协议如:UDP。既然是API那,上面说的其实就是它的原理。下面说一下它的使用。大概说一下。

1ServerSocket:是服务端来监听的类。监听方法accept()。

2客户端:创建Socket对象,设定IP和Port

3当有新的客户端连接时可以通过ServerSocket类获取Socket。而Socket就是我们的通讯渠道。

4发送和读取数据分别使用OutputStream和InputStream而这两个类是从Socket获取的。

其实Socket的基本使用就是这么简单,但是在其实项目中这样是无法满足需求的。实际上大多数场景都是需要一对多的提供服务。

使用多线程实现多客户端的通信

实现服务器与多个客户端进行通信, 可以接受多个客户端的请求并进行回复

应用多线程来实现服务器与多客户端之间的通信

1、服务器端创建ServerSocket,循环调用accept()等待客户端连接

2、客户端创建一个Socket并请求和服务器端连接

3、服务器端接受客户端请求,创建socket与该客户建立专线连接

4、建立连接的两个socket在一个单独的线程上对话

5、服务器端继续等待新的连接


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/10238227.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-06
下一篇 2023-05-06

发表评论

登录后才能评论

评论列表(0条)

保存