Windows Socket 编程 : 支持多线程(TCP)(环境:VS2010)

几点说明:

(1)发送的数据不能有空格;

(2)这是控制台应用程序;

1、UserMesInfo.h 公共文件,客户端和服务器端公用;

 1 #ifndef  User_Mes_Sock
 2 #define  User_Mes_Sock
 3 #include <winsock2.h>
 4 #endif
 5 
 6 const short  MesLogin   =  1001;
 7 const short  MesError   =  1002;
 8 const short  MesNormal  =  1003;
 9 const short  LoginSuc   =  1004;
10 const short  MesToAll   =  1005;
11 const short  OnLineUser =  1010;
12 
13 
14 //User Struct
15 struct UserInfo
16 {
17     short        userId;
18     char         userName[32];
19     SOCKET       userSock;
20     LONG         userAddr;
21     UserInfo     *pNext;
22 };
23 
24 //Message Struct
25 struct MesInfo
26 {
27     short        MesType;
28     char         fromUserName[32];
29     char         toUserName[32];
30     char         MesContent[1024];
31 };

 

2、TCP:客户端程序

  1 #include <iostream>
  2 #include <stdlib.h>
  3 #include <WinSock2.h>
  4 
  5 #include "UserMesInfo.h"
  6 
  7 #pragma comment(lib,"ws2_32.lib")
  8 
  9 using namespace std;
 10 
 11 BOOL isLogin = false;
 12 
 13 
 14 string charToString(char temp[])
 15 {
 16     string tempStr = "";
 17     for(int i = 0; i < sizeof(temp); i++)
 18         tempStr += temp[i];
 19     return tempStr;
 20 }
 21 
 22 BOOL SendMes(SOCKET servSocket)
 23 {
 24     SOCKET servSock = servSocket;
 25     while(TRUE)
 26     {
 27         int tempWho;
 28         char sendBuff[1024] = {0};
 29         if(isLogin)
 30         {
 31             printf(" '1' : speak to ONE ;\n '2' : speak to ALL ;\n '3' : OnLine Users ; \n '4' : Exit ;\n");
 32 
 33             cin>>tempWho;
 34         }
 35         if( isLogin && tempWho == 1)
 36         {
 37             //To One
 38             printf("Please input NAME you want to CHAT : ");
 39             char toName[32] = {0};
 40             scanf("%s", toName);
 41             memcpy(sendBuff, &MesNormal, 2);
 42             memcpy(sendBuff+2, toName, 32);
 43             printf("Please input what do you want to say : ");
 44             char Message[1000] = {0};
 45             scanf("%s", Message);
 46             memcpy(sendBuff+34, Message, strlen(Message));
 47             send(servSock, sendBuff, sizeof(sendBuff)+1, 0);
 48         } else if(isLogin && tempWho == 2){
 49             //To ALL
 50             printf("Please input DATA : ");
 51             char Message[1000] = {0};
 52             scanf("%s", Message);
 53 
 54             memcpy(sendBuff, &MesToAll, 2);
 55             memcpy(sendBuff+2, Message, strlen(Message));
 56             send(servSock, sendBuff, sizeof(sendBuff)+1, 0);
 57 
 58         } else if(isLogin && tempWho == 3){
 59             char getOnLineUsers[4];
 60             memcpy(getOnLineUsers, &OnLineUser, 2);
 61             send(servSock, getOnLineUsers, sizeof(getOnLineUsers), 0);
 62         } else if(isLogin && tempWho == 4){
 63             break;
 64         } else if(isLogin){
 65             printf("You input Error! Please Again !");
 66         }
 67         
 68     }
 69     return TRUE;
 70 }
 71 
 72 
 73 DWORD WINAPI ProcThread(LPVOID lpParameter)
 74 {
 75     SOCKET cliSocket = *(SOCKET*)lpParameter;
 76 
 77     //SOCKADDR_IN sockFrom ;
 78     //int length = sizeof(SOCKADDR);
 79 
 80     char recvBuf[1024] = {0};
 81 
 82     while(true)
 83     {
 84         memset(recvBuf, 0x00, 1024);
 85         int recvLen = recv(cliSocket, recvBuf, 1024, 0);
 86         if(recvLen > 0)
 87         {
 88             short megId = *(short*)recvBuf;
 89             switch(megId)
 90             {
 91             case LoginSuc:
 92                 {
 93                     //char userName[32] = {0};
 94                     //memcpy(userName, recvBuf+2, 4);
 95                     printf("Login Success !\n");
 96                     isLogin = true;
 97                 }
 98                 break;
 99             case MesNormal:
100                 {
101                     char Mess[1000];
102                     memcpy(Mess, recvBuf+2, sizeof(recvBuf)-2);
103                     printf(" ==> Me :%s\n", Mess);
104                     
105                 }
106                 break;
107             case MesToAll:
108                 {
109                     char Mess[1000];
110                     memcpy(Mess, recvBuf+2, sizeof(recvBuf)-2);
111                     printf(" ==> All :%s\n", Mess);
112                 }
113                 break;
114             case OnLineUser:
115                 {
116                     char onLineUser[100] = {0};
117                     
118                     memcpy(onLineUser, recvBuf+2, sizeof(recvBuf)-2);
119 
120                     //string userStr = charToString(onLineUser);
121                     
122                     for(int i =0; i < sizeof(onLineUser); i++)
123                         cout<<onLineUser[i];
124 
125                     //printf("%s\n", userStr);
126                     cout<<endl<<onLineUser<<endl;
127                     printf("\n");
128             
129                 }
130                 break;
131             default :
132                 break;
133             }
134         }//end if
135     }// end while
136 
137     return 0;
138 }
139 
140 int main()
141 {
142     WORD wVersionRequested;
143     WSADATA wsaData;
144     int err;
145 
146     wVersionRequested = MAKEWORD(2, 2);
147 
148     err = WSAStartup(wVersionRequested, &wsaData);
149     if (err != 0) {
150         printf("WSAStartup failed with error: %d\n", err);
151         return 1;
152     }
153 
154     if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
155         /* Tell the user that we could not find a usable */
156         /* WinSock DLL.                                  */
157         printf("Could not find a usable version of Winsock.dll\n");
158         WSACleanup();
159         return 1;
160     }
161     else
162         printf("The Winsock 2.2 dll was found okay\n");
163 
164 
165     SOCKET clientSock = socket(AF_INET, SOCK_STREAM, 0);
166 
167     if(clientSock == -1)
168     {
169         perror("socket创建出错!"); 
170         exit(1);
171     }
172 
173     SOCKADDR_IN addrClient;
174     addrClient.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
175     addrClient.sin_family = AF_INET;
176     addrClient.sin_port = htons(6000);
177 
178 
179     int ret = connect(clientSock, (sockaddr*)&addrClient, sizeof(SOCKADDR));
180     if (ret)
181     {
182         printf("连接失败\n");
183         return -1;
184     }
185 
186     HANDLE thHandle = CreateThread(NULL, 0, ProcThread, &clientSock, 0, NULL);
187 
188     if(NULL == thHandle)
189     {
190         cout<<"Create Thread failed !"<<endl;
191         return -1;
192     }
193 
194     char userName[32];
195     printf("Please input name : ");
196     scanf_s("%s", userName, 31);
197 
198     /*
199     UserInfo* user = new UserInfo;
200     user->userSock = clientSock;
201     strcpy_s(user->userName, userName);
202     user->userAddr = addrClient.sin_addr.S_un.S_addr;
203     */
204     
205     char loginInfo[64] = {0};
206     memcpy(loginInfo, &MesLogin, 2);
207     memcpy(loginInfo+2, userName, strlen(userName));
208 
209     
210     //int a = send(clientSock, loginInfo, strlen(loginInfo), 0);
211     int a = send(clientSock, loginInfo, strlen(loginInfo), 0);
212     
213     SendMes(clientSock);
214 
215     //Sleep(20000);
216     //closesocket(clientSock);
217     CloseHandle(thHandle);
218     WSACleanup();
219 
220     
221     system("PAUSE");
222     return 0;
223 }

 

3、TCP:服务器端程序

  1 #include <iostream>
  2 #include <cstdlib>
  3 #include <winsock2.h>
  4 #include <string>
  5 #include <Windows.h>
  6 #include "UserMesInfo.h"
  7 
  8 #pragma comment(lib,"ws2_32.lib")
  9 
 10 using namespace std;
 11 
 12 UserInfo *gUserInfo ;
 13 
 14 string charToString(char temp[])
 15 {
 16     string tempStr = "";
 17     for(int i = 0; i < sizeof(temp); i++)
 18         tempStr += temp[i];
 19     return tempStr;
 20 }
 21 
 22 
 23 DWORD WINAPI ProcMes(LPVOID lpParameter)
 24 {
 25     SOCKET cliSocket = ((UserInfo*)lpParameter)->userSock;
 26     //SOCKADDR_IN sockFrom ;
 27 
 28     char recvBuf[1024];
 29     //int length = sizeof(SOCKADDR);
 30 
 31     while(true)
 32     {
 33         memset(recvBuf, 0x00, 1024);
 34         recv(cliSocket, recvBuf, 1024, 0);
 35         
 36         short MesType = *(short*)recvBuf;
 37 
 38         switch(MesType)
 39         {
 40         case MesLogin:
 41             {
 42                 static short USERID = 1001;
 43                 UserInfo* userInfo = new UserInfo;
 44                 char* userName = (char*)(recvBuf + 2);
 45                 strcpy_s(userInfo->userName, userName);
 46                 userInfo->userId = USERID++;
 47                 userInfo->userSock = cliSocket;
 48                 userInfo->userAddr = ((UserInfo*)lpParameter)->userAddr;
 49                 userInfo->pNext = NULL;
 50 
 51                 if(!gUserInfo)
 52                 {
 53                     gUserInfo = userInfo;
 54                 }else 
 55                 {
 56                     userInfo->pNext = gUserInfo;
 57                     gUserInfo = userInfo;
 58                 }
 59                 printf("Login  :  %s ==> %d !\n", userInfo->userName, userInfo->userId);
 60                 
 61                 char loginInfo[4] = {0};
 62                 memcpy(loginInfo, &LoginSuc, 2);
 63                 
 64                 int i = send(cliSocket, loginInfo, strlen(loginInfo), 0);
 65                 
 66             }
 67             break;
 68         case MesNormal:
 69             {
 70                 //printf("The Normal Message !");
 71                 char toName[32] = {0};
 72                 memcpy(toName, recvBuf+2, 32);
 73                 cout<<toName<<endl;
 74                 char Message[1000] = {0};
 75                 memcpy(Message, recvBuf+34, sizeof(recvBuf)-34);
 76                 printf("%s\n", Message);
 77 
 78                 char sendMes[1006];
 79                 memcpy(sendMes, &MesNormal, 2);
 80                 memcpy(sendMes+2, recvBuf+34, sizeof(recvBuf)-34);
 81                 
 82                 //send(toSock, sendMes, sizeof(sendMes), 0);
 83 
 84                 UserInfo* tempUser = gUserInfo;
 85                 BOOL sendFlag = false;
 86                 while(tempUser)
 87                 {
 88                     if(!memcmp(toName, tempUser->userName, strlen(toName)))
 89                     {
 90                         SOCKET toSock = tempUser->userSock;
 91                         send(toSock, sendMes, strlen(sendMes)+1, 0);
 92                         sendFlag = true;
 93                     }
 94                     tempUser = tempUser->pNext;
 95                 }
 96                 if(!sendFlag)
 97                 {
 98                     printf("Send Failed !\n");
 99                 }
100                 
101             }
102             break;
103         case MesToAll:
104             {
105                 char Message[1000] = {0};
106                 memcpy(Message, recvBuf+2, sizeof(recvBuf)-2);
107                 UserInfo* tempUser = gUserInfo;
108                 char sendMes[1002];
109                 memcpy(sendMes, &MesToAll, 2);
110                 memcpy(sendMes+2, Message, sizeof(Message));
111                 while(tempUser)
112                 {
113                     SOCKET toSock = tempUser->userSock;
114                     int i = send(toSock, sendMes, strlen(sendMes)+1, 0);
115                     if(i > 0)
116                     {
117                         printf("Send To %s Success !\n", tempUser->userName);
118                     }
119                     tempUser = tempUser->pNext;
120                 }
121             }
122             break;
123         case MesError:
124             //printf("The Error Message !");
125             break; 
126         case OnLineUser:
127             {
128                 
129                 char onLineUserBuff[1000] = {0};
130                 UserInfo* tempUser = gUserInfo;
131                 
132                 memcpy(onLineUserBuff, &OnLineUser, 2);
133 
134                 int i = 0;
135                 string userStr = "";
136                 while(tempUser)
137                 {
138                     userStr += charToString(tempUser->userName);
139                     //处理方式有问题
140                     //memcpy(onLineUserBuff+2, tempUser->userName, 32);
141                     //send(cliSocket, onLineUserBuff, sizeof(onLineUserBuff), 0);
142                     tempUser = tempUser->pNext;
143                 }
144                 memcpy(onLineUserBuff+2, userStr.c_str(), userStr.length());
145                 send(cliSocket, onLineUserBuff, sizeof(onLineUserBuff), 0);
146                         
147             }
148             break;
149         default:
150             //printf("The Default Process !");
151             break;
152         }
153     
154     }
155 
156     
157     return 0;
158 }
159 
160 int main()
161 {
162     WORD wVersionRequested;
163     WSADATA wsaData;
164     int err;
165 
166     wVersionRequested = MAKEWORD(2, 2);
167 
168     err = WSAStartup(wVersionRequested, &wsaData);
169     if (err != 0) {
170         printf("WSAStartup failed with error: %d\n", err);
171         return 1;
172     }
173 
174     if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
175         /* Tell the user that we could not find a usable */
176         /* WinSock DLL.                                  */
177         printf("Could not find a usable version of Winsock.dll\n");
178         WSACleanup();
179         return 1;
180     }
181     else
182         printf("The Winsock 2.2 dll was found okay\n");
183 
184 
185     SOCKET servSock = socket(AF_INET, SOCK_STREAM, 0);
186 
187     SOCKADDR_IN addrServ ;
188     addrServ.sin_family = AF_INET;
189     addrServ.sin_port = htons(6000);
190     addrServ.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
191 
192     bind(servSock, (SOCKADDR*)&addrServ, sizeof(SOCKADDR));
193 
194     if(listen(servSock, 20) == SOCKET_ERROR)
195     {
196         printf("listen failed with error: %ld\n", WSAGetLastError());
197         closesocket(servSock);
198         WSACleanup();
199         return -1;
200     }
201 
202 
203     while(true)
204     {
205         //wait for users Login, and create thread for it
206         SOCKADDR_IN cliAddr;
207         int length = sizeof(SOCKADDR);
208 
209         SOCKET cliSock = accept(servSock, (SOCKADDR*)&cliAddr, &length);
210 
211         if(INVALID_SOCKET == cliSock)
212         {
213             printf("listen failed with error: %ld\n", WSAGetLastError());
214             closesocket(cliSock);
215             WSACleanup();
216             return -1;
217         }
218 
219         UserInfo* user = new UserInfo;
220 
221         user->userSock = cliSock;
222         user->userAddr = cliAddr.sin_addr.S_un.S_addr;
223 
224         //cout<<sizeof(user->userName)<<endl;
225 
226         HANDLE loginHandle = CreateThread(NULL, 0, ProcMes, (LPVOID)user, 0, NULL);
227 
228         if(NULL == loginHandle)
229         {
230             cout<<"Create Thread failed !"<<endl;
231             return -1;
232         }
233         CloseHandle(loginHandle);
234 
235     }
236     //Sleep(20000);
237     closesocket(servSock);
238     WSACleanup();
239 
240     system("PAUSE");
241     return 0;
242 }
posted @ 2012-11-17 22:17  china_victory  阅读(12196)  评论(4编辑  收藏  举报