一个基于TCP的多线程文件下载模型
服务端代码:
View Code
1 UINT MTServerThread(LPVOID pParam);
2 UINT ClientThread(LPVOID pParam);
3 BOOL ParseCmd(char *str, CString& cmd, CString& params);
4 BOOL SendFile(SOCKET s, CString fname);
5
6 SOCKET server;
7
8
9 void CFileServerDlg::OnButton1()
10 {
11 // TODO: Add your control notification handler code here
12
13 AfxBeginThread(MTServerThread,0);
14 GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE);
15 }
16
17 UINT MTServerThread(LPVOID pParam)
18 {
19 sockaddr_in local;
20 local.sin_family=AF_INET;
21 local.sin_addr.s_addr=INADDR_ANY;
22 local.sin_port=htons((u_short)20248);
23 server=socket(AF_INET,SOCK_STREAM,0);
24 if(server==INVALID_SOCKET)
25 {
26 return 0;
27 }
28 if(bind(server,(sockaddr*)&local,sizeof(local))!=0)
29 {
30 return 0;
31 }
32 if(listen(server,10)!=0)
33 {
34 return 0;
35 }
36
37 SOCKET client;
38 sockaddr_in from;
39 int fromlen=sizeof(from);
40
41 while(true)
42 {
43 client=accept(server,(struct sockaddr*)&from,&fromlen);
44 AfxBeginThread(ClientThread,(LPVOID)client);
45 }
46 return 0;
47 }
48
49
50 UINT ClientThread(LPVOID pParam)
51 {
52 char buff[512];
53 CString cmd;
54 CString params;
55 int n;
56 int x;
57 BOOL auth=false;
58 SOCKET client=(SOCKET)pParam;
59 strcpy(buff,"#Server Ready.\r\n");
60 send(client,buff,strlen(buff),0);
61 while(true)
62 {
63 n=recv(client,buff,512,0);
64 if(n==SOCKET_ERROR )
65 break;
66 buff[n]=0;
67
68 if(ParseCmd(buff,cmd,params))
69 {
70 if(cmd=="QUIT")
71 break;
72 if(cmd=="AUTH")
73 {
74 if(params=="passwd")
75 {
76 auth=true;
77 strcpy(buff,"#You are logged in.\r\n");
78 }
79 else
80 {
81 strcpy(buff,"!Bad password.\r\n");
82 }
83 send(client,buff,strlen(buff),0);
84 }
85 if(cmd=="FILE")
86 {
87 if(auth)
88 {
89 if(SendFile(client,params))
90 sprintf(buff,"#File %s sent successfully.\r\n",params);
91 else
92 sprintf(buff,"!File %s could not be opened.\r\n",params);
93 x=send(client,buff,strlen(buff),0);
94 }
95 else
96 {
97 strcpy(buff,"!You are not logged in.\r\n");
98 send(client,buff,strlen(buff),0);
99 }
100 }
101 }
102 else
103 {
104 strcpy(buff,"!Invalid command.\r\n");
105 send(client,buff,strlen(buff),0);
106 }
107
108 }
109
110 closesocket(client);
111 return 0;
112 }
113
114 BOOL ParseCmd(char *str, CString& cmd, CString& params)
115 {
116 int n;
117 CString tmp=str;
118 tmp.TrimLeft();
119 tmp.TrimRight();
120 if((n=tmp.Find(' '))==-1)
121 {
122 tmp.MakeUpper();
123 if(tmp!="QUIT")
124 return false;
125 cmd=tmp;
126 return true;
127 }
128 cmd=tmp.Left(n);
129 params=tmp.Mid(n+1);
130 cmd.MakeUpper();
131 if((cmd!="AUTH") && (cmd!="FILE"))
132 return false;
133 return true;
134 }
135
136 BOOL SendFile(SOCKET s, CString fname)
137 {
138 CFile f;
139 BOOL p=f.Open(fname,CFile::modeRead);
140 char buff[1024];
141 int y;
142 int x;
143 if(!p)
144 return false;
145 while(true)
146 {
147 y=f.Read(buff,1024);
148 TRACE("File Send:%d\n",y);
149 x=send(s,buff,y,0);
150 if(y<1024)
151 {
152 f.Close();
153 break;
154 }
155 }
156
157 return true;
158 }
客户端代码:
View Code
1 void CFileCilentDlg::OnButton1()
2 {
3 UpdateData();
4 // TODO: Add your control notification handler code here
5 SOCKET conn;
6 const char* servername="127.0.0.1";
7 struct hostent *hp;
8 struct sockaddr_in server;
9 unsigned int addr;
10
11 conn=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
12 if(conn==INVALID_SOCKET)
13 {
14 return;
15 }
16 if(inet_addr(servername)==INADDR_NONE)
17 {
18 hp=gethostbyname(servername);
19 }
20 else
21 {
22 addr=inet_addr(servername);
23 hp=gethostbyaddr((char*)&addr,sizeof(addr),AF_INET);
24 }
25 if(hp==NULL)
26 {
27 closesocket(conn);
28 return;
29 }
30 server.sin_addr.s_addr=*((unsigned long*)hp->h_addr);
31 server.sin_family=AF_INET;
32 server.sin_port=htons(20248);
33
34 if(connect(conn,(struct sockaddr*)&server,sizeof(server)))
35 {
36 closesocket(conn);
37 return;
38 }
39
40 char buff[512];
41 int z;
42 z=recv(conn,buff,512,0);
43 buff[z]=0;
44
45 strcpy(buff,"auth passwd\r\n");
46 send(conn,buff,strlen(buff),0);
47
48 z=recv(conn,buff,512,0);
49 buff[z]=0;
50
51 sprintf(buff,"file %s\r\n",m_fileName);
52 send(conn,buff,strlen(buff),0);
53
54 CFile f;
55 char *fname;
56 char fname2[256];
57 if(!(fname=strrchr(m_fileName,'\\')))
58 strcpy(fname2,m_fileName);
59 else
60 strcpy(fname2,fname+1);
61
62 int n=m_fileName.ReverseFind('\\');
63 CString fileName=m_fileName.Right(m_fileName.GetLength()-(n+1));
64 CString filepath="D:\\"+fileName;
65 MessageBox(filepath);
66 f.Open(filepath,CFile::modeCreate | CFile::modeWrite);
67 bool first=true;
68 bool second=false;
69
70 while(true)
71 {
72 z=recv(conn,buff,128,0);
73 if(z==SOCKET_ERROR)
74 {
75 MessageBox("\r\n\r\nsocket error socket error socket error\r\n");
76 break;
77 }
78 if(second)
79 {
80 if(NoFile(buff,128)<128)
81 {
82 MessageBox("File"+m_fileName+" not found on server\r\n");
83 break;
84 }
85 second=false;
86 }
87 if(first)
88 {
89 if(NoFile(buff,128)<128)
90 {
91 MessageBox("File "+m_fileName+" not found on server\r\n");
92 break;
93 }
94 first=false;
95 second=true;
96 }
97
98 int b;
99 if((b=EndFile(buff,z))<z)
100 {
101 f.Write(buff,b);
102 MessageBox(" has been saved.\r\n");
103 break;
104 }
105 f.Write(buff,z);
106 }
107 f.Close();
108 shutdown(conn,2);
109 closesocket(conn);
110 }
111
112 int CFileCilentDlg::EndFile(char *buff, int len)
113 {
114 int pos=len;
115 for(int u=0;u<(len-4);u++)
116 {
117 if(buff[u]=='#')
118 if(buff[u+1]=='F')
119 if(buff[u+2]=='i')
120 if(buff[u+3]=='l')
121 if(buff[u+4]=='e')
122 {
123 pos=u;
124 break;
125 }
126 }
127 return pos;
128 }
129
130 int CFileCilentDlg::NoFile(char *buff, int len)
131 {
132 int pos=len;
133 for(int u=0;u<(len-4);u++)
134 {
135 if(buff[u]=='!')
136 if(buff[u+1]=='F')
137 if(buff[u+2]=='i')
138 if(buff[u+3]=='l')
139 if(buff[u+4]=='e')
140 {
141 pos=u;
142 break;
143 }
144 }
145 return pos;
146 }
posted on 2011-12-23 22:12 Sunny_NUAA 阅读(481) 评论(0) 编辑 收藏 举报