我的代码如下:
Server:
public static Socket ServerSocket;
public static void listen()
{
try
{
ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
String hostName = Dns.GetHostName();
IPAddress ServerIP = Dns.GetHostAddresses(hostName)[0];
IPEndPoint serverHost = new IPEndPoint(ServerIP, 5555);
ServerSocket.Bind(serverHost);
ServerSocket.Listen(1000);//----------------1
ThreadStart serverThreadStart = new ThreadStart(serverThreadProc);
Thread serverThread = new Thread(serverThreadStart);
serverThread.Start();
}
catch (Exception ex)
{
Console.WriteLine("主socket创建失败");
Console.WriteLine(ex.StackTrace.ToString());
}
}
private static void serverThreadProc()
{
while (true)
{
try
{
//-----q1
Socket threadSocket = ServerSocket.Accept();//---------------4
byte[] rcvB = new byte[1024];
threadSocket.Receive(rcvB); //---------------2
string msg = Encoding.Unicode.GetString(rcvB);
string[] Separators = new string[] { "||" };
string[] distribute = msg.Split(Separators, StringSplitOptions.RemoveEmptyEntries);
//判断接收到的数据的类型
switch (distribute[0])
{
case "1":
byte[] msg = Encoding.Unicode.GetBytes("true");
threadSocket.send(msg); //-------------------3
byte[] msg2 = new byte[1024];
threadSocket.Receive(msg2);//-----------------5 //----q2
............................
break;
case "2":
............................
break;
default:
Console.WriteLine("接收数据错误!");
break;
}
}
catch (Exception ex)
{
Console.WriteLine("线程监听错误:" + ex.StackTrace.ToString());
}
}
}
问题1: ServerSocket.Listen(1000);这条语句是写在listen方法里(如上),还是写在serverThreadProc方法里(//----q1 处)呢?我是要实现线程的.
问题2: 对于socket的Receive()方法,参数是根据什么来指定的呢?
我参考过MSDN,但里面说的很模糊,我总是不能确定什么时侯写threadSocket.Receive(bytes),写threadSocket.Receive(bytes,SocketFlags.**),还是写其他的形式.这到底有什么不同啊?
还有我看过的例子里,SocketFlags都取None,这和不设置SocketFlags有什么分别呢?
问题3: 同问题2差不多,在socket的Send()方法里,参数是根据什么来指定的呢? 如果指定了SocketFlags,那么是不是Server和Client双方都要设计SocketFlags,而且取值要一样呢?
问题4: Socket threadSocket = ServerSocket.Accept();这条语句到底是怎样工作的?
在MSDN中,解释Accept是: 以同步方式从侦听套接字的连接请求队列中提取第一个挂起的连接请求,然后创建并返回新的Socket。
我在调试过程中,疑惑这个"然后创建并返回的新的 Socket"到底是怎样的"新". 我发现我的threadSocket的LocalEndPoint和ServerSocket的LocalEndPoint是一样的(IP和端口);那么在threadSocket与Client通讯时,在我看来ServerSocket是不能在Accept其它请求的吧,那这与只使用一个Socket有什么分别呢?这样的话,那我原本想要的"线程"效果其实也没实现了吧.
其实是不是真的像我所说的那样呢?
原本我以为这个"然后创建并返回的新的 Socket"会是一个绑定到另一个端口的Socket,这样我才有点清楚"新"的所在.但结果不是,真难理解.
问题5: 同步与异步具体怎样理解啊? 我现在设计一个即时聊天系统,那么Server和Client之间的数据传输是应该是同步还是应该是异步呢?同步的理解是不是若有数据发送过来,这边就要马上把数据取出呢?若不是马上接收,待再有数据发送过来时,是不是原来未取出的数据就被覆盖了呢?
问题6: 如上面的代码,当程序方法serverThreadProc里以 while-try-switch-case"1" 的流程执行,当正在执行的语句是//----q2所标记的语句时:
1,若Client过了很久之后才向Server发送数据,那么语句//----q2中的threadSocket是不是一直等待,等到Client发送数据过来呢?
2,若Client没有向Server发送数据,而是关闭了与Server的通讯的Socket,那么threadSocket是不是也马上关闭,再跳出switch呢?
问题7: Server和Client通讯的两个Socket都要显式关闭吗? 如Server向Client发送数据,在Server发送完数据后是不是要Socket.Close()了呢? 或者在Client接收完数据后就Socket.Close()呢?
我想,若要保证Client能在Server关闭连接前接收数据,那么Client必须先于Server关闭Socket.
我又请教过同学,有人说:只要一方关闭了Socket,那么另一方就能检测到,这样另一方就会隐式地关闭Socket,而不需要显式地Socket.Close().是不是这样啊?
如果真如同学所说,那么 如Server向Client发送数据,在Server发送完数据后就不用Socket.Close(),而是在Client接收完数据后就Socket.Close()吧.有待求证啊.