多线程Socket 编程实现局域网通信
利用多线程 Socket 编程实现 TCP 协议。 在局域网内实现多个 IP 的信息通信。
服务器:
接收所有局域网内客户端发来的信息, 并将此信息转发给其他所以的客户端。 采用多线程实现局域网内每个在线客户端的信息监听。
客户端:
接受服务器发来的信息,或发送信息给服务器, 再有服务器转发给其他在线客户端。
服务器代码:
using
System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace multithreadserv
{
class Threadtcpserver
{
private Socket server;
private int userNum; // 在线客户数量
private int socketNum; // 连接服务段的数量
private Socket[] socketUser = new Socket[ 40 ]; // 存储在线的客户端
// 将客服端 nowClient 发来的信息 data,发送给其他在线的每个客户端,不包括 nowClient客服端。
private void SendAllUser( byte [] data, Socket nowClient)
{
if (userNum > 0 )
{
for ( int i = 0 ; i < socketNum; i ++ )
{
if (socketUser[i].Equals(nowClient)) continue ;
// 在发送过程中可能有些客户已经离线,会发生异常
try
{
socketUser[i].Send(data);
}
catch
{
// 当一个发现异常后,说明 socket[i] 已经离线,需要从socketUser[] 数组中将其删除
Socket temp = socketUser[i];
socketUser[i] = socketUser[socketNum - 1 ];
i -- ;
socketNum -- ;
}
}
}
}
// 客户端 client 的接受信息的方法
private void ReceiveData( object client)
{
Socket nowClient = (Socket)client;
while ( true )
{
int res = 0 ;
byte [] bytes = new byte [ 1024 ];
// 不段的接受客户端发来的信息, 当客户端离线后,退出。
try
{
res = nowClient.Receive(bytes);
}
catch
{
// client 离线,更新userNum 值
userNum -- ;
Console.WriteLine( " 现在有:{0} 个客户在连接中。 " , userNum);
return ;
}
string str = Encoding.UTF8.GetString(bytes, 0 , res);
byte [] data = Encoding.UTF8.GetBytes(str);
// 将该信息发送给其他客户端
SendAllUser(data, nowClient);
}
}
// 侦听上线的客户端
private void AccpetUser()
{
while ( true )
{
// 当侦听到一个客户端上线后,更新socketUser[],并给此客户端开一个接受信息的线程
Socket nowClient = server.Accept();
socketUser[socketNum ++ ] = nowClient;
userNum ++ ;
Console.WriteLine( " 现在有:{0} 个客户在连接中。 " , userNum);
// 开一个线程, 接受 nowClient 发来的信息。
// 这里调用的方法为有参数的方法, 需要使用委托。
Thread nowThread = new Thread( new ParameterizedThreadStart(ReceiveData));
// nowThread.IsBackground = true;
nowThread.Start(nowClient);
}
}
// 构造函数
public Threadtcpserver()
{
userNum = 0 ;
socketNum = 0 ;
// 初始化 IP 地址
IPAddress local = IPAddress.Parse( " 192.168.1.101 " ); // 客户端的 IPAddress 地址
IPEndPoint iep = new IPEndPoint(local, 3000 ); // 端口为3000
server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// 将套接字与本地终结点绑定
server.Bind(iep);
// 在本地 3000 端口行上进行监听
server.Listen( 20 );
Console.WriteLine( " 等待客户级进行连接... " );
AccpetUser();
}
static void Main( string [] args)
{
Threadtcpserver instance = new Threadtcpserver();
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace multithreadserv
{
class Threadtcpserver
{
private Socket server;
private int userNum; // 在线客户数量
private int socketNum; // 连接服务段的数量
private Socket[] socketUser = new Socket[ 40 ]; // 存储在线的客户端
// 将客服端 nowClient 发来的信息 data,发送给其他在线的每个客户端,不包括 nowClient客服端。
private void SendAllUser( byte [] data, Socket nowClient)
{
if (userNum > 0 )
{
for ( int i = 0 ; i < socketNum; i ++ )
{
if (socketUser[i].Equals(nowClient)) continue ;
// 在发送过程中可能有些客户已经离线,会发生异常
try
{
socketUser[i].Send(data);
}
catch
{
// 当一个发现异常后,说明 socket[i] 已经离线,需要从socketUser[] 数组中将其删除
Socket temp = socketUser[i];
socketUser[i] = socketUser[socketNum - 1 ];
i -- ;
socketNum -- ;
}
}
}
}
// 客户端 client 的接受信息的方法
private void ReceiveData( object client)
{
Socket nowClient = (Socket)client;
while ( true )
{
int res = 0 ;
byte [] bytes = new byte [ 1024 ];
// 不段的接受客户端发来的信息, 当客户端离线后,退出。
try
{
res = nowClient.Receive(bytes);
}
catch
{
// client 离线,更新userNum 值
userNum -- ;
Console.WriteLine( " 现在有:{0} 个客户在连接中。 " , userNum);
return ;
}
string str = Encoding.UTF8.GetString(bytes, 0 , res);
byte [] data = Encoding.UTF8.GetBytes(str);
// 将该信息发送给其他客户端
SendAllUser(data, nowClient);
}
}
// 侦听上线的客户端
private void AccpetUser()
{
while ( true )
{
// 当侦听到一个客户端上线后,更新socketUser[],并给此客户端开一个接受信息的线程
Socket nowClient = server.Accept();
socketUser[socketNum ++ ] = nowClient;
userNum ++ ;
Console.WriteLine( " 现在有:{0} 个客户在连接中。 " , userNum);
// 开一个线程, 接受 nowClient 发来的信息。
// 这里调用的方法为有参数的方法, 需要使用委托。
Thread nowThread = new Thread( new ParameterizedThreadStart(ReceiveData));
// nowThread.IsBackground = true;
nowThread.Start(nowClient);
}
}
// 构造函数
public Threadtcpserver()
{
userNum = 0 ;
socketNum = 0 ;
// 初始化 IP 地址
IPAddress local = IPAddress.Parse( " 192.168.1.101 " ); // 客户端的 IPAddress 地址
IPEndPoint iep = new IPEndPoint(local, 3000 ); // 端口为3000
server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// 将套接字与本地终结点绑定
server.Bind(iep);
// 在本地 3000 端口行上进行监听
server.Listen( 20 );
Console.WriteLine( " 等待客户级进行连接... " );
AccpetUser();
}
static void Main( string [] args)
{
Threadtcpserver instance = new Threadtcpserver();
}
}
}
客服端代码:
using
System;
using System.Collections.Generic;
using System.Text;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace multithreadclient
{
class ClientSocket
{
// public string names;
public Socket client;
public ClientSocket()
{
client = null ;
}
public void ReceiveData()
{
byte [] data = new byte [ 1024 ];
while ( true )
{
int res = 0 ;
try
{
res = client.Receive(data);
}
catch
{
Console.WriteLine( " 与服务器断开连接! " );
return ;
}
Console.WriteLine(Encoding.UTF8.GetString(data, 0 , res));
Console.WriteLine();
}
}
static void Main( string [] args)
{
// byte[] buf = new byte[1024];
ClientSocket ads = new ClientSocket();
IPAddress local = IPAddress.Parse( " 192.168.1.101 " ); // 服务器的 IPAddres 地址
IPEndPoint iep = new IPEndPoint(local, 3000 );
try
{
ads.client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
ads.client.Connect(iep);
}
catch (SocketException)
{
Console.WriteLine( " 无法连接到服务器 " );
Console.ReadLine();
return ;
}
finally
{
}
Console.Write( " 连接成功, 请输入昵称: " );
string names = Console.ReadLine();
Thread newThread = new Thread( new ThreadStart(ads.ReceiveData));
newThread.Start();
names += " 说: " ;
while ( true )
{
// 在控制台上输入一条消息
// Console.WriteLine("我想说:");
Console.WriteLine();
string input = Console.ReadLine();
input = names + input;
ads.client.Send(Encoding.UTF8.GetBytes(input));
}
Console.WriteLine( " 断开与服务器的连接... " );
ads.client.Close();
Console.ReadLine();
}
}
}
using System.Collections.Generic;
using System.Text;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace multithreadclient
{
class ClientSocket
{
// public string names;
public Socket client;
public ClientSocket()
{
client = null ;
}
public void ReceiveData()
{
byte [] data = new byte [ 1024 ];
while ( true )
{
int res = 0 ;
try
{
res = client.Receive(data);
}
catch
{
Console.WriteLine( " 与服务器断开连接! " );
return ;
}
Console.WriteLine(Encoding.UTF8.GetString(data, 0 , res));
Console.WriteLine();
}
}
static void Main( string [] args)
{
// byte[] buf = new byte[1024];
ClientSocket ads = new ClientSocket();
IPAddress local = IPAddress.Parse( " 192.168.1.101 " ); // 服务器的 IPAddres 地址
IPEndPoint iep = new IPEndPoint(local, 3000 );
try
{
ads.client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
ads.client.Connect(iep);
}
catch (SocketException)
{
Console.WriteLine( " 无法连接到服务器 " );
Console.ReadLine();
return ;
}
finally
{
}
Console.Write( " 连接成功, 请输入昵称: " );
string names = Console.ReadLine();
Thread newThread = new Thread( new ThreadStart(ads.ReceiveData));
newThread.Start();
names += " 说: " ;
while ( true )
{
// 在控制台上输入一条消息
// Console.WriteLine("我想说:");
Console.WriteLine();
string input = Console.ReadLine();
input = names + input;
ads.client.Send(Encoding.UTF8.GetBytes(input));
}
Console.WriteLine( " 断开与服务器的连接... " );
ads.client.Close();
Console.ReadLine();
}
}
}