1. UserMesInfo.h 公共文件,客户端和服务器端公用;
#ifndef User_Mes_Sock
#define User_Mes_Sock
#include <winsock2.h>
#endif
const short MesLogin = 1001;
const short MesError = 1002;
const short MesNormal = 1003;
const short LoginSuc = 1004;
const short MesToAll = 1005;
const short OnLineUser = 1010;
//User Struct
struct UserInfo
{
short userId;
char userName[32];
SOCKET userSock;
LONG userAddr;
UserInfo *pNext;
};
//Message Struct
struct MesInfo
{
short MesType;
char fromUserName[32];
char toUserName[32];
char MesContent[1024];
};
2. TCP:客户端程序
#include <iostream>
#include <stdlib.h>
#include <WinSock2.h>
#include "UserMesInfo.h"
#pragma comment(lib,"ws2_32.lib")
using namespace std;
BOOL isLogin = false;
string charToString(char temp[])
{
string tempStr = "";
for(int i = 0; i < sizeof(temp); i++)
tempStr += temp[i];
return tempStr;
}
BOOL SendMes(SOCKET servSocket)
{
SOCKET servSock = servSocket;
while(TRUE)
{
int tempWho;
char sendBuff[1024] = {0};
if(isLogin)
{
printf(" '1' : speak to ONE ;\n '2' : speak to ALL ;\n '3' : OnLine Users ; \n '4' : Exit ;\n");
cin>>tempWho;
}
if( isLogin && tempWho == 1)
{
//To One
printf("Please input NAME you want to CHAT : ");
char toName[32] = {0};
scanf("%s", toName);
memcpy(sendBuff, &MesNormal, 2);
memcpy(sendBuff+2, toName, 32);
printf("Please input what do you want to say : ");
char Message[1000] = {0};
scanf("%s", Message);
memcpy(sendBuff+34, Message, strlen(Message));
send(servSock, sendBuff, sizeof(sendBuff)+1, 0);
} else if(isLogin && tempWho == 2){
//To ALL
printf("Please input DATA : ");
char Message[1000] = {0};
scanf("%s", Message);
memcpy(sendBuff, &MesToAll, 2);
memcpy(sendBuff+2, Message, strlen(Message));
send(servSock, sendBuff, sizeof(sendBuff)+1, 0);
} else if(isLogin && tempWho == 3){
char getOnLineUsers[4];
memcpy(getOnLineUsers, &OnLineUser, 2);
send(servSock, getOnLineUsers, sizeof(getOnLineUsers), 0);
} else if(isLogin && tempWho == 4){
break;
} else if(isLogin){
printf("You input Error! Please Again !");
}
}
return TRUE;
}
DWORD WINAPI ProcThread(LPVOID lpParameter)
{
SOCKET cliSocket = *(SOCKET*)lpParameter;
//SOCKADDR_IN sockFrom ;
//int length = sizeof(SOCKADDR);
char recvBuf[1024] = {0};
while(true)
{
memset(recvBuf, 0x00, 1024);
int recvLen = recv(cliSocket, recvBuf, 1024, 0);
if(recvLen > 0)
{
short megId = *(short*)recvBuf;
switch(megId)
{
case LoginSuc:
{
//char userName[32] = {0};
//memcpy(userName, recvBuf+2, 4);
printf("Login Success !\n");
isLogin = true;
}
break;
case MesNormal:
{
char Mess[1000];
memcpy(Mess, recvBuf+2, sizeof(recvBuf)-2);
printf(" ==> Me :%s\n", Mess);
}
break;
case MesToAll:
{
char Mess[1000];
memcpy(Mess, recvBuf+2, sizeof(recvBuf)-2);
printf(" ==> All :%s\n", Mess);
}
break;
case OnLineUser:
{
char onLineUser[100] = {0};
memcpy(onLineUser, recvBuf+2, sizeof(recvBuf)-2);
//string userStr = charToString(onLineUser);
for(int i =0; i < sizeof(onLineUser); i++)
cout<<onLineUser[i];
//printf("%s\n", userStr);
cout<<endl<<onLineUser<<endl;
printf("\n");
}
break;
default :
break;
}
}//end if
}// end while
return 0;
}
int main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(2, 2);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0) {
printf("WSAStartup failed with error: %d\n", err);
return 1;
}
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
printf("Could not find a usable version of Winsock.dll\n");
WSACleanup();
return 1;
}
else
printf("The Winsock 2.2 dll was found okay\n");
SOCKET clientSock = socket(AF_INET, SOCK_STREAM, 0);
if(clientSock == -1)
{
perror("socket创建出错!");
exit(1);
}
SOCKADDR_IN addrClient;
addrClient.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
addrClient.sin_family = AF_INET;
addrClient.sin_port = htons(6000);
int ret = connect(clientSock, (sockaddr*)&addrClient, sizeof(SOCKADDR));
if (ret)
{
printf("连接失败\n");
return -1;
}
HANDLE thHandle = CreateThread(NULL, 0, ProcThread, &clientSock, 0, NULL);
if(NULL == thHandle)
{
cout<<"Create Thread failed !"<<endl;
return -1;
}
char userName[32];
printf("Please input name : ");
scanf_s("%s", userName, 31);
/*
UserInfo* user = new UserInfo;
user->userSock = clientSock;
strcpy_s(user->userName, userName);
user->userAddr = addrClient.sin_addr.S_un.S_addr;
*/
char loginInfo[64] = {0};
memcpy(loginInfo, &MesLogin, 2);
memcpy(loginInfo+2, userName, strlen(userName));
//int a = send(clientSock, loginInfo, strlen(loginInfo), 0);
int a = send(clientSock, loginInfo, strlen(loginInfo), 0);
SendMes(clientSock);
//Sleep(20000);
//closesocket(clientSock);
CloseHandle(thHandle);
WSACleanup();
system("PAUSE");
return 0;
}
3.TCP:服务器端程序
#include <iostream>
#include <cstdlib>
#include <winsock2.h>
#include <string>
#include <Windows.h>
#include "UserMesInfo.h"
#pragma comment(lib,"ws2_32.lib")
using namespace std;
UserInfo *gUserInfo ;
string charToString(char temp[])
{
string tempStr = "";
for(int i = 0; i < sizeof(temp); i++)
tempStr += temp[i];
return tempStr;
}
DWORD WINAPI ProcMes(LPVOID lpParameter)
{
SOCKET cliSocket = ((UserInfo*)lpParameter)->userSock;
//SOCKADDR_IN sockFrom ;
char recvBuf[1024];
//int length = sizeof(SOCKADDR);
while(true)
{
memset(recvBuf, 0x00, 1024);
recv(cliSocket, recvBuf, 1024, 0);
short MesType = *(short*)recvBuf;
switch(MesType)
{
case MesLogin:
{
static short USERID = 1001;
UserInfo* userInfo = new UserInfo;
char* userName = (char*)(recvBuf + 2);
strcpy_s(userInfo->userName, userName);
userInfo->userId = USERID++;
userInfo->userSock = cliSocket;
userInfo->userAddr = ((UserInfo*)lpParameter)->userAddr;
userInfo->pNext = NULL;
if(!gUserInfo)
{
gUserInfo = userInfo;
}else
{
userInfo->pNext = gUserInfo;
gUserInfo = userInfo;
}
printf("Login : %s ==> %d !\n", userInfo->userName, userInfo->userId);
char loginInfo[4] = {0};
memcpy(loginInfo, &LoginSuc, 2);
int i = send(cliSocket, loginInfo, strlen(loginInfo), 0);
}
break;
case MesNormal:
{
//printf("The Normal Message !");
char toName[32] = {0};
memcpy(toName, recvBuf+2, 32);
cout<<toName<<endl;
char Message[1000] = {0};
memcpy(Message, recvBuf+34, sizeof(recvBuf)-34);
printf("%s\n", Message);
char sendMes[1006];
memcpy(sendMes, &MesNormal, 2);
memcpy(sendMes+2, recvBuf+34, sizeof(recvBuf)-34);
//send(toSock, sendMes, sizeof(sendMes), 0);
UserInfo* tempUser = gUserInfo;
BOOL sendFlag = false;
while(tempUser)
{
if(!memcmp(toName, tempUser->userName, strlen(toName)))
{
SOCKET toSock = tempUser->userSock;
send(toSock, sendMes, strlen(sendMes)+1, 0);
sendFlag = true;
}
tempUser = tempUser->pNext;
}
if(!sendFlag)
{
printf("Send Failed !\n");
}
}
break;
case MesToAll:
{
char Message[1000] = {0};
memcpy(Message, recvBuf+2, sizeof(recvBuf)-2);
UserInfo* tempUser = gUserInfo;
char sendMes[1002];
memcpy(sendMes, &MesToAll, 2);
memcpy(sendMes+2, Message, sizeof(Message));
while(tempUser)
{
SOCKET toSock = tempUser->userSock;
int i = send(toSock, sendMes, strlen(sendMes)+1, 0);
if(i > 0)
{
printf("Send To %s Success !\n", tempUser->userName);
}
tempUser = tempUser->pNext;
}
}
break;
case MesError:
//printf("The Error Message !");
break;
case OnLineUser:
{
char onLineUserBuff[1000] = {0};
UserInfo* tempUser = gUserInfo;
memcpy(onLineUserBuff, &OnLineUser, 2);
int i = 0;
string userStr = "";
while(tempUser)
{
userStr += charToString(tempUser->userName);
//处理方式有问题
//memcpy(onLineUserBuff+2, tempUser->userName, 32);
//send(cliSocket, onLineUserBuff, sizeof(onLineUserBuff), 0);
tempUser = tempUser->pNext;
}
memcpy(onLineUserBuff+2, userStr.c_str(), userStr.length());
send(cliSocket, onLineUserBuff, sizeof(onLineUserBuff), 0);
}
break;
default:
//printf("The Default Process !");
break;
}
}
return 0;
}
int main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(2, 2);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0) {
printf("WSAStartup failed with error: %d\n", err);
return 1;
}
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
printf("Could not find a usable version of Winsock.dll\n");
WSACleanup();
return 1;
}
else
printf("The Winsock 2.2 dll was found okay\n");
SOCKET servSock = socket(AF_INET, SOCK_STREAM, 0);
SOCKADDR_IN addrServ ;
addrServ.sin_family = AF_INET;
addrServ.sin_port = htons(6000);
addrServ.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
bind(servSock, (SOCKADDR*)&addrServ, sizeof(SOCKADDR));
if(listen(servSock, 20) == SOCKET_ERROR)
{
printf("listen failed with error: %ld\n", WSAGetLastError());
closesocket(servSock);
WSACleanup();
return -1;
}
while(true)
{
//wait for users Login, and create thread for it
SOCKADDR_IN cliAddr;
int length = sizeof(SOCKADDR);
SOCKET cliSock = accept(servSock, (SOCKADDR*)&cliAddr, &length);
if(INVALID_SOCKET == cliSock)
{
printf("listen failed with error: %ld\n", WSAGetLastError());
closesocket(cliSock);
WSACleanup();
return -1;
}
UserInfo* user = new UserInfo;
user->userSock = cliSock;
user->userAddr = cliAddr.sin_addr.S_un.S_addr;
//cout<<sizeof(user->userName)<<endl;
HANDLE loginHandle = CreateThread(NULL, 0, ProcMes, (LPVOID)user, 0, NULL);
if(NULL == loginHandle)
{
cout<<"Create Thread failed !"<<endl;
return -1;
}
CloseHandle(loginHandle);
}
//Sleep(20000);
closesocket(servSock);
WSACleanup();
system("PAUSE");
return 0;
}
转自http://www.cnblogs.com/china-victory/archive/2012/11/17/2775404.html