TCP Socket 同步问题。。

hecker728 2009-11-16 10:25:17
public void TcpThread()
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
ReceIpEp = new IPEndPoint(ipAddress, this.port);
socket.Bind(ReceIpEp);
socket.Listen(0);
while (true)
{
Socket connection = socket.Accept();
CConnection conn = new CConnection(connection);
gpsConnection.Frmgps = this.frmgps;
Thread thread = new Thread(new ThreadStart(gpsConnection.WaitForSendData));
thread.Name = connection.RemoteEndPoint.ToString();
thread.Start();
}
}
以上的线程函数在一个类中,用于接收TCP连接。CConnection类用于每一个TCP连接的数据收发,
并且每一个TCP连接都专门开启一个线程。
Class CConnection
{
private Socket connSocket

public void CConnection(Socket conn)
{
this.connSocket=conn
}
public void WaitForSendData()
{
while (true)
{
bytes = new byte[1024];
this.connSocket.Blocking = true;
int bytesLength = this.connSocket.Receive(bytes);
........
}
}


}

现在的问题是,,每次连接来的时候创建CConnection conn对象传入Socket,并开起一个线程。
1,每次创建CConnection conn会不会覆盖之前创建的CConnection conn对象?不
2,每个线程,public void WaitForSendData()访问的是同一个对象引用么?
3,这种情况下需要同步么,如何同步?
4,CConnection类中还有很多其他字段,那么每个线程访问的是不同的对象的字段还是同一个对象的字段?

问题问的很乱,因为对于这块的理解很乱,希望大家能够看的明白。。也希望能让我也明白
不晓得这个算不算是对同一代码块的访问,,但是每个线程都在不同的对象中。。
...全文
143 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
qldsrx 2009-11-17
  • 打赏
  • 举报
回复
好的方法就是不要自己创建Thread,使用线程池。自己创建Thread唯一的好处只有“可以随时挂起线程”,但是Socket线程是不能随便挂起的,挂起会有异常的,所以你应该学习如何使用Socket.BeginXXX方法来操作,让系统来管理线程资源。
hecker728 2009-11-17
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 qldsrx 的回复:]
你的CConnection的对象互不相干,只要你不使用静态成员变量,就无需考虑同步。

不过你的代码有个问题,
Thread thread = new Thread(new ThreadStart(gpsConnection.WaitForSendData));
这部分代码不应该这么写,你这样运行了一个新的线程,却没有捕获这个thread,会导致程序退出进程仍就运行,运行的是你的后台线程。如果要用Thread,你必须在程序退出前终止所有的Thread。所以你应该用ThreadPool,或者你可以使用socket.BeginAccept来创建系统默认的ThreadPool来异步执行。
[/Quote]

上面的代码只是一个测试代码。我现在的设计上就是使用的同步方式,TCP的连接数可能会达到50-100,所以也会同时创建这么多的线程。关于管理这些线程,我是这么想的,在创建线程的时候,可以将线程ID和Socket
绑定,在Socket连接断开的时候,释放该线程的所有资源。至于程序退出,简单点直接KIll掉进程。像你所说的,终止所有线程后退出也可以。

现在有个问题向你请教,,可以根据Thread.Name来终止线程吗,不能的话,,在程序退出时,或Socket断开连接,,有什么好的方式退出线程,释资源。
hecker728 2009-11-16
  • 打赏
  • 举报
回复
坛子里的人呢?趁服务器挂了,,在线等!!!
lybelmont 2009-11-16
  • 打赏
  • 举报
回复
线程池 和 异步方式 最大的问题是 时序上很难控制 (都交给系统去处理了)
不过 你的线程互相之间影响小 就可以使用,操作简单
huing 2009-11-16
  • 打赏
  • 举报
回复
thread的开销是蛮大的,TheadPool是比较不错的选择
linguanyu315 2009-11-16
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 qldsrx 的回复:]
你的CConnection的对象互不相干,只要你不使用静态成员变量,就无需考虑同步。

不过你的代码有个问题,
Thread thread = new Thread(new ThreadStart(gpsConnection.WaitForSendData));
这部分代码不应该这么写,你这样运行了一个新的线程,却没有捕获这个thread,会导致程序退出进程仍就运行,运行的是你的后台线程。如果要用Thread,你必须在程序退出前终止所有的Thread。所以你应该用ThreadPool,或者你可以使用socket.BeginAccept来创建系统默认的ThreadPool来异步执行。
[/Quote]

ThreadPool是一个比较好的解决方案, 我现在也用TheadPool, 效果不错.
MOmo400 2009-11-16
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 qldsrx 的回复:]
你的CConnection的对象互不相干,只要你不使用静态成员变量,就无需考虑同步。

不过你的代码有个问题,
Thread thread = new Thread(new ThreadStart(gpsConnection.WaitForSendData));
这部分代码不应该这么写,你这样运行了一个新的线程,却没有捕获这个thread,会导致程序退出进程仍就运行,运行的是你的后台线程。如果要用Thread,你必须在程序退出前终止所有的Thread。所以你应该用ThreadPool,或者你可以使用socket.BeginAccept来创建系统默认的ThreadPool来异步执行。
[/Quote]

学习...
qldsrx 2009-11-16
  • 打赏
  • 举报
回复
你的CConnection的对象互不相干,只要你不使用静态成员变量,就无需考虑同步。

不过你的代码有个问题,
Thread thread = new Thread(new ThreadStart(gpsConnection.WaitForSendData));
这部分代码不应该这么写,你这样运行了一个新的线程,却没有捕获这个thread,会导致程序退出进程仍就运行,运行的是你的后台线程。如果要用Thread,你必须在程序退出前终止所有的Thread。所以你应该用ThreadPool,或者你可以使用socket.BeginAccept来创建系统默认的ThreadPool来异步执行。
leayh 2009-11-16
  • 打赏
  • 举报
回复
如果是多个连接,要用到异步,异步的回调就在另一个线程中进行的。
hecker728 2009-11-16
  • 打赏
  • 举报
回复
to xu_2007:

你的意思是,用CConnection类里的属性字段不需要同步。。

要是用到其他类的对象就要同步,是这样的吗
xu_2007 2009-11-16
  • 打赏
  • 举报
回复
CConnection这个类里面的接收代码里面,只要不处理公共变量就不需要同步,如果要处理公共对象的话就一定要同步,公共对象是指主类里面的某个对象!

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧