我們的項(xiàng)目是用DotNet實(shí)現(xiàn)Socket連接,用多線程處理多用戶。我就談一下在實(shí)現(xiàn)過程中遇到的問題。下面是我
服務(wù)器的簡化實(shí)現(xiàn)。
private Socket clientSocket;
public void Start()
{
Thread thread=new Thread(new ThreadStart(MainService));
thread.Start();
}
void MainService()
{
listener=new TcpListener(111111);
listener.Start();
while(true)
{
Socket s= listener.AcceptSocket();//幀聽客戶連接
clientSocket=s;
Thread clientservice = new Thread(new ThreadStart(ClientService));
clientservice.Start();
Thread.Sleep(200);//1、等待傳值給線程中的變量,防止多用戶造成沖突
}
}
void ClientService()
{
string command;
string receiveStr;
string fileName,fileSize;
Socket sock=clientSocket;
EndPoint oldEP=sock.RemoteEndPoint;
byte[] bb=new byte[200];
while(true)
{
ii=sock.ReceiveFrom(bb,ref oldEP);//接收數(shù)據(jù)
if(ii==0)//2、客戶端連接斷開,就會(huì)不停接收0個(gè)字節(jié)
{
break;
}
receiveStr=Encoding.Default.GetString(bb,0,bb.Length);
command=ReadLineFrom(receiveStr,1).ToLower();//ReadLineFrom讀取字符串中的一行數(shù)據(jù)
Switch(command)
{
cace “upload“:
fileName=ReadLineFrom(receiveStr,2);
fileSize=ReadLineFrom(receiveStr,3);
uploadFile(sock,fileName,Int32.Parse(fileSize));//接受數(shù)據(jù)方法,
break;
....................
}
}
void uploadFile(Socket sock,string fileName,int fileSize)
{
int loadSize=0;
byte[] bb;
int blen=102400;
NetworkStream stream=new NetworkStream(sock);
FileStream fs=File.OpenWrite(tempstr);
while(loadSize
{
if(loadSize>fileSize-102400)
blen=fileSize-loadSize;
bb=new byte[blen];
int ii=stream.Read(bb,0,bb.Length);//3、實(shí)際接受數(shù)據(jù)時(shí)每次可能沒有10240個(gè)字節(jié)
fs.Write(bb,0,ii);
loadSize+=ii;
}
fs.Close();
stream.Close();
}
1、等待傳值給線程中的變量,防止多用戶造成沖突
2、客戶端連接斷開,就會(huì)不停接收0個(gè)字節(jié)
判斷客戶端是否斷開要用這個(gè)方法實(shí)現(xiàn),Sokcet里帶的Connected不起作用,只要連接上,中途不出現(xiàn)發(fā)送和或接收數(shù)據(jù)錯(cuò)誤,客戶斷開與否都是返回true。Poll(100,SelectMode...)返回任何模式都是true。
3、實(shí)際接受數(shù)據(jù)時(shí)每次可能沒有10240個(gè)字節(jié)
客戶端我就不寫了,用TcpClient連接就可以了,當(dāng)然實(shí)際應(yīng)用中,可能就要自己寫規(guī)則了
這些問題解決了,只要做適當(dāng)?shù)奶幚恚曨l,聲音都不是問題了。
posted on 2010-01-25 20:47
becket_zheng 閱讀(193)
評(píng)論(0) 編輯 收藏 所屬分類:
C#