SOCKET通信程序源码

最近一段时间在学习了SOCKET,下面是程序源代码,都是在VC6.0环境下,用WIN32控制台程序写的:

1.TCP协议:

先写服务器端的程序,创建一个服务器端的工程,新建立一个C++源文件,代码如下:

//sockServ.cpp
#include <iostream>
#include <Windows.h>
#pragma comment(lib, "WS2_32")  // 链接到WS2_32.lib 
using namespace std;

#define  PORT 4000
//#define  IP_ADDRESS "192.168.1.145"
#define  IP_ADDRESS "127.0.0.1"

DWORD WINAPI ClientThread(LPVOID lpParameter)
{
SOCKET CientSocket = (SOCKET)lpParameter;
int Ret = 0;
char RecvBuffer[MAX_PATH];
char SendBuffer[MAX_PATH];

while ( true )
{
memset(RecvBuffer, 0x00, sizeof(RecvBuffer));
Ret = recv(CientSocket, RecvBuffer, MAX_PATH, 0);
if ( Ret == 0 || Ret == SOCKET_ERROR ) 
{
cout<<"客户端退出!"<<endl;
break;
}
cout<<"接收到客户信息为:"<<RecvBuffer<<endl;
//服务器端发送信息  
cout<<"服务器端向客户端发送如下的数据,快点在此输入吧!:"<<endl;
cin.getline(SendBuffer, sizeof(SendBuffer));
Ret = send(CientSocket, SendBuffer, (int)strlen(SendBuffer), 0);
if ( Ret == SOCKET_ERROR )
{
cout<<"Send Info Error::"<<GetLastError()<<endl;
break;
}
}
return 0;
}

int main(int argc, char* argv[])
{
WSADATA  Ws;
SOCKET ServerSocket, CientSocket;
struct sockaddr_in LocalAddr, ClientAddr;//sockaddr_in是TCP/IP使用的数据结构
int Ret = 0;
int AddrLen = 0;
HANDLE hThread = NULL;

//Init Windows Socket
if ( WSAStartup(MAKEWORD(2,2), &Ws) != 0 )//socket使用2.2版本的
{
cout<<"Init Windows Socket Failed::"<<GetLastError()<<endl;
return -1;
}

//Create Socket
//第一个参数表示是INTERNET协议簇,第二个参数SOCK_STREAM表示是用TCP协议来进行通信。第三个参数是0表示让系统自动选择
ServerSocket = socket(AF_INET, SOCK_STREAM, 0);
//ServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if ( ServerSocket == INVALID_SOCKET )
{
cout<<"Create Socket Failed::"<<GetLastError()<<endl;
return -1;
}

LocalAddr.sin_family = AF_INET;//INTERNET协议簇
//LocalAddr.sin_addr.s_addr = inet_addr(IP_ADDRESS);//这句也可以
//LocalAddr.sin_addr.s_addr = INADDR_ANY;//这句也可以 等同于 LocalAddr.sin_addr.s_addr = inet_addr("0.0.0.0");
LocalAddr.sin_addr.S_un.S_addr = INADDR_ANY; 
LocalAddr.sin_port = htons(PORT);
memset(LocalAddr.sin_zero, 0x00, 8);

//Bind Socket
Ret = bind(ServerSocket, (struct sockaddr*)&LocalAddr, sizeof(LocalAddr));
if ( Ret != 0 )
{
cout<<"Bind Socket Failed::"<<GetLastError()<<endl;
return -1;
}

Ret = listen(ServerSocket, 10);//用ServerSocket来进行监听,监听最多10个客户端的请求
if ( Ret != 0 )
{
cout<<"listen Socket Failed::"<<GetLastError()<<endl;
return -1;
}

cout<<"服务端已经启动"<<endl;
while ( true )//因为是服务器端,要不停的监听客户端的请求
{
AddrLen = sizeof(ClientAddr);
//用CientSocket来进行通信
CientSocket = accept(ServerSocket, (struct sockaddr*)&ClientAddr, &AddrLen);
if ( CientSocket == INVALID_SOCKET )
{
cout<<"Accept Failed::"<<GetLastError()<<endl;
break;
}

cout<<"客户端连接::"<<inet_ntoa(ClientAddr.sin_addr)<<":"<<ClientAddr.sin_port<<endl;

hThread = CreateThread(NULL, 0, ClientThread, (LPVOID)CientSocket, 0, NULL);
if ( hThread == NULL )
{
cout<<"Create Thread Failed!"<<endl;
break;
}
CloseHandle(hThread);
}

closesocket(ServerSocket);
closesocket(CientSocket);
WSACleanup();

return 0;
}

然后再新建一个客户端的工程,新建一个C++源文件,在其中写入如下代码:(注意:只能是2个工程,肯定不能写在同一个工作里面,因为如果写在1个工程里面,那么就有两个main函数,这样程序肯定不允许的),客户端代码如下:

//sockCli.cpp
#include <iostream>
#include <Windows.h>
using namespace std;
#pragma comment(lib, "WS2_32")  // 链接到WS2_32.lib 

#define  PORT 4000
//#define  IP_ADDRESS "192.168.1.145"
#define  IP_ADDRESS "127.0.0.1"

int main(int argc, char* argv[])
{
WSADATA  Ws;
SOCKET CientSocket;
struct sockaddr_in ServerAddr;
int Ret = 0;
int AddrLen = 0;
HANDLE hThread = NULL;
char SendBuffer[MAX_PATH];
char RecvBuffer[MAX_PATH];

//Init Windows Socket
if ( WSAStartup(MAKEWORD(1,1), &Ws) != 0 )//客户端用的SOCKET库的版本和服务器端一样,就算不一样,也可以正常通信
{
cout<<"Init Windows Socket Failed::"<<GetLastError()<<endl;
return -1;
}

//Create Socket
CientSocket = socket(AF_INET, SOCK_STREAM, 0);//创建了一个客户端的SOCKET
if ( CientSocket == INVALID_SOCKET )
{
cout<<"Create Socket Failed::"<<GetLastError()<<endl;
return -1;
}

ServerAddr.sin_family = AF_INET;
ServerAddr.sin_addr.s_addr = inet_addr(IP_ADDRESS);
ServerAddr.sin_port = htons(PORT);
memset(ServerAddr.sin_zero, 0x00, 8);
//连接到服务器,连接的服务器的地址在上面中设定
Ret = connect(CientSocket,(struct sockaddr*)&ServerAddr, sizeof(ServerAddr));
if ( Ret == SOCKET_ERROR )
{
cout<<"Connect Error::"<<GetLastError()<<endl;
return -1;
}
else
{
cout<<"连接成功!"<<endl;
}

while ( true )
{
cout<<"你是客户端哦,快点给服务器端说点什么吧,好让它知道你的存在!:"<<endl;
cin.getline(SendBuffer, sizeof(SendBuffer));
//向服务器端发送数据
Ret = send(CientSocket, SendBuffer, (int)strlen(SendBuffer), 0);
if ( Ret == SOCKET_ERROR )
{
cout<<"Send Info Error::"<<GetLastError()<<endl;
break;
}

memset(RecvBuffer, 0x00, sizeof(RecvBuffer));
//从服务器端接收数据
Ret = recv(CientSocket, RecvBuffer, MAX_PATH, 0);
if ( Ret == 0 || Ret == SOCKET_ERROR ) 
{
cout<<"客户端退出!"<<endl;
break;
}
cout<<"接收到服务器信息为:"<<RecvBuffer<<endl;
}

closesocket(CientSocket);
WSACleanup();

return 0;
}

在启动的时候,先启动服务器端,再启动客户端,程序运行结果如下所示:

2.UDP协议

下面是UDP协议的通信:也是WIN32控制台程序,不过启动的时候不用像TCP一样必须要先启动服务器端,可以先启动客户端,再启动服务器端,可以启动若干个客户端,在下面的图中有说明,图中就是启动了2个客户端,启动了一个服务器端,注意:只能启动一个服务器端,下面是程序源码:

//sockServ.cpp
#include <iostream>
#include <Windows.h>
#pragma comment(lib, "WS2_32")  // 链接到WS2_32.lib 
using namespace std;

#define  PORT 5000
//#define  IP_ADDRESS "192.168.1.145"
#define  IP_ADDRESS "127.0.0.1"

int main(int argc, char* argv[])
{
WSADATA  Ws;
SOCKET ServerSocket, CientSocket = 0;
struct sockaddr_in LocalAddr, ClientAddr;//sockaddr_in是TCP/IP使用的数据结构
int Ret = 0;
int AddrLen = 0;
char RecvBuffer[MAX_PATH] = {0};
char SendBuffer[MAX_PATH] = {0};

//Init Windows Socket
if ( WSAStartup(MAKEWORD(2,2), &Ws) != 0 )//socket使用2.2版本的
{
cout<<"Init Windows Socket Failed::"<<GetLastError()<<endl;
return -1;
}

//Create Socket
//第一个参数表示是INTERNET协议簇,第二个参数SOCK_STREAM表示是用TCP协议来进行通信。第三个参数是0表示让系统自动选择
ServerSocket = socket(AF_INET, SOCK_DGRAM, 0);
//ServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if ( ServerSocket == INVALID_SOCKET )
{
cout<<"Create Socket Failed::"<<GetLastError()<<endl;
return -1;
}

LocalAddr.sin_family = AF_INET;//INTERNET协议簇
//LocalAddr.sin_addr.s_addr = inet_addr(IP_ADDRESS);
//LocalAddr.sin_addr.S_un.S_addr = INADDR_ANY;
LocalAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
LocalAddr.sin_port = htons(PORT);
memset(LocalAddr.sin_zero, 0x00, 8);

//Bind Socket
Ret = bind(ServerSocket, (sockaddr*)&LocalAddr, sizeof(LocalAddr));
if ( SOCKET_ERROR == Ret )
{
cout<<"Bind Socket Failed::"<<GetLastError()<<endl;
return -1;
}
int saddrlen = sizeof(sockaddr_in);
cout<<"服务器端启动啦……"<<endl;

while(1)
{
memset(RecvBuffer,0,sizeof(RecvBuffer));
memset(SendBuffer,0,sizeof(SendBuffer));
Ret = recvfrom(ServerSocket,RecvBuffer,MAX_PATH,0,(sockaddr*)&ClientAddr,&saddrlen);
if(SOCKET_ERROR == Ret)
{
cout<<"服务器端接收数据错了!"<<endl;
}
else
{
cout<<"我是服务器端,我从客户端 "<<inet_ntoa(ClientAddr.sin_addr)<<
" 接收的数据为:"<<RecvBuffer<<endl;
cout<<"服务器端向客户端发送如下的数据,快点在此输入吧!:"<<endl;
cin.getline(SendBuffer, sizeof(SendBuffer));
Ret = sendto(ServerSocket,SendBuffer,(int)strlen(SendBuffer),0,(sockaddr*)&ClientAddr,saddrlen);
if(SOCKET_ERROR == Ret)
{
cout<<"服务器端发送数据错了!"<<endl;
}
} 
}
closesocket(ServerSocket);
closesocket(CientSocket);
WSACleanup();
return 0;
}
客户端的程序如下:
//sockCli.cpp
#include <iostream>
#include <Windows.h>
using namespace std;
#pragma comment(lib, "WS2_32")  // 链接到WS2_32.lib 

#define  PORT 5000
//#define  IP_ADDRESS "192.168.1.145"
#define  IP_ADDRESS "127.0.0.1"

int main(int argc, char* argv[])
{
WSADATA  Ws;
SOCKET CientSocket;
struct sockaddr_in ServerAddr;
int Ret = 0;
int AddrLen = 0;
HANDLE hThread = NULL;
char SendBuffer[MAX_PATH];
char RecvBuffer[MAX_PATH];

//Init Windows Socket
if ( WSAStartup(MAKEWORD(1,1), &Ws) != 0 )//客户端用的SOCKET库的版本和服务器端一样,就算不一样,也可以正常通信
{
cout<<"Init Windows Socket Failed::"<<GetLastError()<<endl;
return -1;
}

//Create Socket
CientSocket = socket(AF_INET, SOCK_DGRAM, 0);//创建了一个客户端的SOCKET
if ( CientSocket == INVALID_SOCKET )
{
cout<<"Create Socket Failed::"<<GetLastError()<<endl;
return -1;
}

ServerAddr.sin_family = AF_INET;
ServerAddr.sin_addr.s_addr = inet_addr(IP_ADDRESS);
ServerAddr.sin_port = htons(PORT);
memset(ServerAddr.sin_zero, 0x00, 8);
int saddrlen = sizeof(sockaddr_in);

while (1)
{
memset(RecvBuffer,0,sizeof(RecvBuffer));
memset(SendBuffer,0,sizeof(SendBuffer));
cout<<"你是客户端哦,快点给服务器端说点什么吧,好让它知道你的存在!:"<<endl;
cin.getline(SendBuffer, sizeof(SendBuffer));
Ret = sendto(CientSocket,SendBuffer,(int)strlen(SendBuffer),0,(sockaddr*)&ServerAddr,saddrlen);
if(SOCKET_ERROR == Ret)
{
cout<<"客户端发送数据错了!"<<endl;
}
else
{
Ret = recvfrom(CientSocket,RecvBuffer,MAX_PATH,0,(sockaddr*)&ServerAddr,&saddrlen);
if(SOCKET_ERROR == Ret)
{
cout<<"客户端接收数据错了!"<<endl;
}
else
{
cout<<"我是客户端,我从服务器端 "<<inet_ntoa(ServerAddr.sin_addr)<<
" 接收的数据为:"<<RecvBuffer<<endl;
} 
}
}

closesocket(CientSocket);
WSACleanup();
return 0;
}

3.TCP用封装的类来实现通信:

服务器端:

#include <iostream>
#include <Windows.h>
#pragma comment(lib, "WS2_32")  // 链接到WS2_32.lib 
using namespace std;

class CTcpSrvSock
{
public:
BOOL InitSocketDll(BYTE lVer,BYTE hVer);//TCP 服务器端也有
BOOL CreateSock(int af,int type,int protocol);
BOOL InitSin(short sin_family,unsigned short sin_port,char FAR *ipAddr);
BOOL BindSin();
BOOL ListenSk(int queNum);
BOOL ConClie();//accept(ServerSocket, (struct sockaddr*)&ClientAddr, &AddrLen);
BOOL CreateCliThread();
static DWORD WINAPI ClientThread(LPVOID lpParameter);
CTcpSrvSock() {}
~CTcpSrvSock();
protected:
private:
WSADATA  Ws;
static SOCKET ServerSocket, CientSocket;
struct sockaddr_in ServerAddr, ClientAddr;//sockaddr_in是TCP/IP使用的数据结构
HANDLE hThread;
};
SOCKET CTcpSrvSock::ServerSocket = 0;
SOCKET CTcpSrvSock::CientSocket = 0;
CTcpSrvSock::~CTcpSrvSock()
{
closesocket(ServerSocket);
closesocket(CientSocket);
WSACleanup();
}
DWORD WINAPI CTcpSrvSock::ClientThread(LPVOID lpParameter)
{
char RecvBuffer[MAX_PATH];
char SendBuffer[MAX_PATH];

SOCKET CientSK = (SOCKET)lpParameter;
int Ret = 0;
while ( true )
{
memset(RecvBuffer, 0x00, sizeof(RecvBuffer));
Ret = recv(CientSocket, RecvBuffer, MAX_PATH, 0);
if ( Ret == 0 || Ret == SOCKET_ERROR ) 
{
cout<<"客户端退出!"<<endl;
break;
}
cout<<"接收到客户信息为:"<<RecvBuffer<<endl;
//服务器端发送信息  
cout<<"服务器端向客户端发送如下的数据,快点在此输入吧!:"<<endl;
cin.getline(SendBuffer, sizeof(SendBuffer));
Ret = send(CientSocket, SendBuffer, (int)strlen(SendBuffer), 0);
if ( Ret == SOCKET_ERROR )
{
cout<<"Send Info Error::"<<GetLastError()<<endl;
break;
}
}
return 0;
}

BOOL CTcpSrvSock::CreateCliThread()
{
hThread = CreateThread(NULL, 0, ClientThread, (LPVOID)CientSocket, 0, NULL);
if ( hThread == NULL )
{
cout<<"Create Thread Failed!"<<endl;
return FALSE;
}
CloseHandle(hThread);
return TRUE;
}

BOOL CTcpSrvSock::ConClie()
{
struct sockaddr_in ClientAddr;//sockaddr_in是TCP/IP使用的数据结构
int AddrLen = sizeof(ClientAddr);
CientSocket = accept(ServerSocket, (struct sockaddr*)&ClientAddr, &AddrLen);
if ( CientSocket == INVALID_SOCKET )
{
cout<<"ConClie Failed::"<<GetLastError()<<endl;
return FALSE;
}
cout<<"客户端连接::"<<inet_ntoa(ClientAddr.sin_addr)<<":"<<ClientAddr.sin_port<<endl;
return TRUE;
}
BOOL CTcpSrvSock::ListenSk(int queNum)
{
//用ServerSocket来进行监听,监听最多10个客户端的请求
if ( listen(ServerSocket, queNum) != 0 )
{
cout<<"listen Socket Failed::"<<GetLastError()<<endl;
return FALSE;
}
cout<<"服务端已经启动,客户端可以过来连接了"<<endl;
return TRUE;
}
BOOL CTcpSrvSock::BindSin()
{
//如下为绑定套接字地址
if(0 != bind(ServerSocket, (struct sockaddr*)&ServerAddr, sizeof(ServerAddr)))
{
cout<<"Bind Socket Failed::"<<GetLastError()<<endl;
return FALSE;
}
int saddrlen = sizeof(sockaddr_in);
cout<<"服务器端启动啦……"<<endl;
return TRUE;
}
//在客户端,初始化的是服务器端的地址
BOOL CTcpSrvSock::InitSin(short sin_family,unsigned short sin_port,char FAR *ipAddr)
{
//ipAddr为...表示的IP地址
ServerAddr.sin_family = sin_family;//AF_INET;//INTERNET协议簇
ServerAddr.sin_addr.s_addr = inet_addr(ipAddr);//s_addr--unsigned long
//skInRet.sin_addr.S_un.S_addr = //INADDR_ANY; 
//skInRet.sin_addr.s_addr = inet_addr(IP_ADDRESS);//这句也可以
//skInRet.sin_addr.s_addr = INADDR_ANY;
//等同于 skInRet.sin_addr.s_addr = inet_addr("0.0.0.0");
//skInRet.sin_addr.S_un.S_addr = INADDR_ANY; 
ServerAddr.sin_port = htons(sin_port);
memset(ServerAddr.sin_zero, 0x00, 8);
return TRUE;
}

BOOL CTcpSrvSock::CreateSock(int af,int type,int protocol)
{
ServerSocket = socket(af, type, protocol);
//ServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if ( ServerSocket == INVALID_SOCKET )
{
cout<<"Create Socket Failed::"<<GetLastError()<<endl;
return FALSE;
}
return TRUE;
}
BOOL CTcpSrvSock::InitSocketDll(BYTE lVer,BYTE hVer)//初始化SOCKET库
{
if ( WSAStartup(MAKEWORD(lVer,hVer), &Ws) != 0 )//socket使用2.2版本的
{
cout<<"Init Windows Socket Failed::"<<GetLastError()<<endl;
return FALSE;
}
return TRUE;
}

class CUdpSrvSock
{
public:
BOOL InitSocketDll(BYTE lVer,BYTE hVer);//TCP 服务器端也有
BOOL CreateSock(int af,int type,int protocol);
BOOL InitSin(short sin_family,unsigned short sin_port,char FAR *ipAddr);
BOOL BindSin();
SOCKET GetCliSocket(){return CientSocket;}
SOCKET GetSrvSocket(){return ServerSocket;}
sockaddr_in GetSrvAdr(){return ServerAddr;}
// sockaddr_in GetCliAdr(){return ClientAddr;}
CUdpSrvSock() {}
~CUdpSrvSock();
protected:
private:
WSADATA  Ws;
static SOCKET ServerSocket, CientSocket;
struct sockaddr_in ServerAddr, ClientAddr;//sockaddr_in是TCP/IP使用的数据结构
HANDLE hThread;

};
SOCKET CUdpSrvSock::ServerSocket = 0;
SOCKET CUdpSrvSock::CientSocket = 0;
CUdpSrvSock::~CUdpSrvSock()
{
closesocket(ServerSocket);
closesocket(CientSocket);
WSACleanup();
}

BOOL CUdpSrvSock::BindSin()
{
//如下为绑定套接字地址
if(0 != bind(ServerSocket, (struct sockaddr*)&ServerAddr, sizeof(ServerAddr)))
{
cout<<"Bind Socket Failed::"<<GetLastError()<<endl;
return FALSE;
}
return TRUE;
}
//在客户端,初始化的是服务器端的地址
BOOL CUdpSrvSock::InitSin(short sin_family,unsigned short sin_port,char FAR *ipAddr)
{
//ipAddr为...表示的IP地址
ServerAddr.sin_family = sin_family;//AF_INET;//INTERNET协议簇
ServerAddr.sin_addr.s_addr = inet_addr(ipAddr);//s_addr--unsigned long
//skInRet.sin_addr.S_un.S_addr = //INADDR_ANY; 
//skInRet.sin_addr.s_addr = inet_addr(IP_ADDRESS);//这句也可以
//skInRet.sin_addr.s_addr = INADDR_ANY;
//等同于 skInRet.sin_addr.s_addr = inet_addr("0.0.0.0");
//skInRet.sin_addr.S_un.S_addr = INADDR_ANY; 
ServerAddr.sin_port = htons(sin_port);
memset(ServerAddr.sin_zero, 0x00, 8);
return TRUE;
}

BOOL CUdpSrvSock::CreateSock(int af,int type,int protocol)
{
ServerSocket = socket(af, type, protocol);
//ServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if ( ServerSocket == INVALID_SOCKET )
{
cout<<"Create Socket Failed::"<<GetLastError()<<endl;
return FALSE;
}
return TRUE;
}
BOOL CUdpSrvSock::InitSocketDll(BYTE lVer,BYTE hVer)//初始化SOCKET库
{
if ( WSAStartup(MAKEWORD(lVer,hVer), &Ws) != 0 )//socket使用2.2版本的
{
cout<<"Init Windows Socket Failed::"<<GetLastError()<<endl;
return FALSE;
}
return TRUE;
}
int TestTCPSerCode()
{
cout<<"TCP服务器端已经启动"<<endl;
CTcpSrvSock tcpSrv1;
tcpSrv1.InitSocketDll(2,2);
tcpSrv1.CreateSock(AF_INET,SOCK_STREAM,0);
tcpSrv1.InitSin(AF_INET,6000,"0.0.0.0");
tcpSrv1.BindSin();
tcpSrv1.ListenSk(5);
while(1)
{
tcpSrv1.ConClie();
tcpSrv1.CreateCliThread();
}
return 0;
}
int TestUDPSerCode()
{
CUdpSrvSock udpsrv;
udpsrv.InitSocketDll(2,2);
udpsrv.CreateSock(AF_INET,SOCK_DGRAM,0);
udpsrv.InitSin(AF_INET,5000,"0.0.0.0");
udpsrv.BindSin();

char SendBuffer[MAX_PATH];
char RecvBuffer[MAX_PATH];
int saddrlen = sizeof(sockaddr_in);
sockaddr_in ClientAddr;
cout<<"UDP服务器端已经启动"<<endl;
while(1)
{
memset(RecvBuffer,0,sizeof(RecvBuffer));
memset(SendBuffer,0,sizeof(SendBuffer));
int Ret = recvfrom(udpsrv.GetSrvSocket(),RecvBuffer,MAX_PATH,0,
(sockaddr*)&ClientAddr,&saddrlen);
if(SOCKET_ERROR == Ret)
{
cout<<"服务器端接收数据错了!"<<endl;
}
else
{
cout<<"我是服务器端,我从客户端 "<<inet_ntoa(ClientAddr.sin_addr)<<
" 接收的数据为:"<<RecvBuffer<<endl;
cout<<"服务器端向客户端发送如下的数据,快点在此输入吧!:"<<endl;
cin.getline(SendBuffer, sizeof(SendBuffer));
Ret = sendto(udpsrv.GetSrvSocket(),SendBuffer,(int)strlen(SendBuffer),0,(sockaddr*)&ClientAddr,saddrlen);
if(SOCKET_ERROR == Ret)
{
cout<<"服务器端发送数据错了!"<<endl;
}
} 
}
return 0;
}

int main()
{
TestTCPSerCode();
//TestUDPSerCode();
return 0;
//UD
}

客户端:

#include <iostream>
#include <Windows.h>
#pragma comment(lib, "WS2_32")  // 链接到WS2_32.lib 
using namespace std;

class CTcpCliSock
{
public:
BOOL InitSocketDll(BYTE lVer,BYTE hVer);//use
BOOL CreateSock(int af,int type,int protocol);//user
BOOL InitSin(short sin_family,unsigned short sin_port,char FAR *ipAddr);//use
//BOOL BindSin();
//BOOL ListenSk(int queNum);
BOOL ConClie();//use
BOOL CreateCliThread();//use
static DWORD WINAPI ClientThread(LPVOID lpParameter);
CTcpCliSock(){}
~CTcpCliSock();
SOCKET GetCliSocket(){return CientSocket;}//new
protected:
private:
WSADATA  Ws;
static SOCKET ServerSocket, CientSocket;
struct sockaddr_in ServerAddr, ClientAddr;//sockaddr_in是TCP/IP使用的数据结构
HANDLE hThread;
char RecvBuffer[MAX_PATH];
char SendBuffer[MAX_PATH];
};
SOCKET CTcpCliSock::ServerSocket = 0;
SOCKET CTcpCliSock::CientSocket = 0;

CTcpCliSock::~CTcpCliSock()
{
closesocket(ServerSocket);
closesocket(CientSocket);
WSACleanup();
}

DWORD WINAPI CTcpCliSock::ClientThread(LPVOID lpParameter)
{
char RecvBuffer[MAX_PATH];
char SendBuffer[MAX_PATH];

cout<<"你是客户端哦,快点给服务器端说点什么吧,好让它知道你的存在!:"<<endl;
cin.getline(SendBuffer, sizeof(SendBuffer));
//向服务器端发送数据
if ( send(CientSocket, SendBuffer, (int)strlen(SendBuffer), 0) == SOCKET_ERROR )
{
cout<<"Send Info Error::"<<GetLastError()<<endl;
}
else
{
memset(RecvBuffer, 0x00, sizeof(RecvBuffer));
//从服务器端接收数据
int Ret = recv(CientSocket, RecvBuffer, MAX_PATH, 0);
if ( Ret == 0 || Ret == SOCKET_ERROR ) 
{
cout<<"客户端退出!"<<endl;
}
else 
{
cout<<"从服务器接收到的信息为:"<<RecvBuffer<<endl;
}
}
return 0;
}

BOOL CTcpCliSock::CreateCliThread()
{
hThread = CreateThread(NULL, 0, ClientThread, (LPVOID)CientSocket, 0, NULL);
if ( hThread == NULL )
{
cout<<"Create Thread Failed!"<<endl;
return FALSE;
}
CloseHandle(hThread);
return TRUE;
}
//在服务器端是用此来联接客户端,在客户端是要连接客户端
BOOL CTcpCliSock::ConClie()
{
if ( connect(CientSocket,(struct sockaddr*)&ServerAddr, sizeof(ServerAddr)) == SOCKET_ERROR )
{
cout<<"Connect Error::"<<GetLastError()<<endl;
return FALSE;
}
cout<<"服务器端连接客户端成功!"<<endl;
return TRUE;
}

BOOL CTcpCliSock::InitSin(short sin_family,unsigned short sin_port,char FAR *ipAddr)
{
//ipAddr为...表示的IP地址
ServerAddr.sin_family = sin_family;//AF_INET;//INTERNET协议簇
ServerAddr.sin_addr.s_addr = inet_addr(ipAddr);//s_addr--unsigned long
//skInRet.sin_addr.S_un.S_addr = //INADDR_ANY; 
//skInRet.sin_addr.s_addr = inet_addr(IP_ADDRESS);//这句也可以
//skInRet.sin_addr.s_addr = INADDR_ANY;//等同于 skInRet.sin_addr.s_addr = inet_addr("0.0.0.0");
//skInRet.sin_addr.S_un.S_addr = INADDR_ANY; 
ServerAddr.sin_port = htons(sin_port);
memset(ServerAddr.sin_zero, 0x00, 8);
return TRUE;
}

BOOL CTcpCliSock::CreateSock(int af,int type,int protocol)
{
CientSocket  = socket(af, type, protocol);
//ServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if ( CientSocket == INVALID_SOCKET )
{
cout<<"Create Socket Failed::"<<GetLastError()<<endl;
return FALSE;
}
return TRUE;
}
BOOL CTcpCliSock::InitSocketDll(BYTE lVer,BYTE hVer)//初始化SOCKET库
{
if ( WSAStartup(MAKEWORD(lVer,hVer), &Ws) != 0 )//socket使用2.2版本的
{
cout<<"Init Windows Socket Failed::"<<GetLastError()<<endl;
return FALSE;
}
return TRUE;
}

class CUdpCliSock
{
public:
BOOL InitSocketDll(BYTE lVer,BYTE hVer);//use
BOOL CreateSock(int af,int type,int protocol);//user
BOOL InitSin(short sin_family,unsigned short sin_port,char FAR *ipAddr);//use
CUdpCliSock(){}
sockaddr_in GetSrvAddr(){return ServerAddr;}
~CUdpCliSock();
SOCKET GetCliSocket(){return CientSocket;}//new
protected:
private:
WSADATA  Ws;
static SOCKET ServerSocket, CientSocket;
struct sockaddr_in ServerAddr, ClientAddr;//sockaddr_in是TCP/IP使用的数据结构
HANDLE hThread;
char RecvBuffer[MAX_PATH];
char SendBuffer[MAX_PATH];
};
SOCKET CUdpCliSock::ServerSocket = 0;
SOCKET CUdpCliSock::CientSocket = 0;

CUdpCliSock::~CUdpCliSock()
{
closesocket(ServerSocket);
closesocket(CientSocket);
WSACleanup();
}

BOOL CUdpCliSock::InitSin(short sin_family,unsigned short sin_port,char FAR *ipAddr)
{
//ipAddr为...表示的IP地址
ServerAddr.sin_family = sin_family;//AF_INET;//INTERNET协议簇
ServerAddr.sin_addr.s_addr = inet_addr(ipAddr);//s_addr--unsigned long
//skInRet.sin_addr.S_un.S_addr = //INADDR_ANY; 
//skInRet.sin_addr.s_addr = inet_addr(IP_ADDRESS);//这句也可以
//skInRet.sin_addr.s_addr = INADDR_ANY;//等同于 skInRet.sin_addr.s_addr = inet_addr("0.0.0.0");
//skInRet.sin_addr.S_un.S_addr = INADDR_ANY; 
ServerAddr.sin_port = htons(sin_port);
memset(ServerAddr.sin_zero, 0x00, 8);
return TRUE;
}

BOOL CUdpCliSock::CreateSock(int af,int type,int protocol)
{
CientSocket  = socket(af, type, protocol);
//ServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if ( CientSocket == INVALID_SOCKET )
{
cout<<"Create Socket Failed::"<<GetLastError()<<endl;
return FALSE;
}
return TRUE;
}
BOOL CUdpCliSock::InitSocketDll(BYTE lVer,BYTE hVer)//初始化SOCKET库
{
if ( WSAStartup(MAKEWORD(lVer,hVer), &Ws) != 0 )//socket使用2.2版本的
{
cout<<"Init Windows Socket Failed::"<<GetLastError()<<endl;
return FALSE;
}
return TRUE;
}

int TestTCPCliCode()
{
CTcpCliSock tcpCli1;
tcpCli1.InitSocketDll(2,2);
tcpCli1.CreateSock(AF_INET,SOCK_STREAM,0);
tcpCli1.InitSin(AF_INET,6000,"127.0.0.1");
tcpCli1.ConClie();
while(1)
{
char SendBuffer[MAX_PATH];
char RecvBuffer[MAX_PATH];
//tcpCli1.CreateCliThread();
cout<<"我是客户端哦,我正在用TCP和服务器端通信,快点给服务器端说点什么吧,好让它知道你的存在!:"<<endl;
cin.getline(SendBuffer, sizeof(SendBuffer));
//向服务器端发送数据
int Ret = send(tcpCli1.GetCliSocket(), SendBuffer, (int)strlen(SendBuffer), 0);
if ( Ret == SOCKET_ERROR )
{
cout<<"Send Info Error::"<<GetLastError()<<endl;
}

memset(RecvBuffer, 0x00, sizeof(RecvBuffer));
//从服务器端接收数据
Ret = recv(tcpCli1.GetCliSocket(), RecvBuffer, MAX_PATH, 0);
if ( Ret == 0 || Ret == SOCKET_ERROR ) 
{
cout<<"客户端退出!"<<endl;
}
cout<<"接收到服务器信息为:"<<RecvBuffer<<endl;
}
return 0;
}

int TestUDPCliCode()
{
CUdpCliSock udpclisk;
udpclisk.InitSocketDll(2,2);
udpclisk.CreateSock(AF_INET,SOCK_DGRAM,0);
udpclisk.InitSin(AF_INET,5000,"127.0.0.1");
char SendBuffer[MAX_PATH];
char RecvBuffer[MAX_PATH];
int saddrlen = sizeof(sockaddr_in);
sockaddr_in myServerAddr;

while (1)
{
memset(RecvBuffer,0,sizeof(RecvBuffer));
memset(SendBuffer,0,sizeof(SendBuffer));
cout<<"我是客户端哦,我正在用UDP和服务器端通信,快点给服务器端说点什么吧,好让它知道你的存在!:"<<endl;
cin.getline(SendBuffer, sizeof(SendBuffer));
int Ret = sendto(udpclisk.GetCliSocket(),SendBuffer,(int)strlen(SendBuffer),
0,(sockaddr*)&(udpclisk.GetSrvAddr()),saddrlen);
if(SOCKET_ERROR == Ret)
{
cout<<"客户端发送数据错了!"<<endl;
break;
}

Ret = recvfrom(udpclisk.GetCliSocket(),RecvBuffer,MAX_PATH,0,
(sockaddr*)&myServerAddr,&saddrlen);
if(SOCKET_ERROR == Ret)
{
cout<<"客户端接收数据错了!"<<endl;
}
else
{
cout<<"我是客户端,我从服务器端 "<<inet_ntoa(myServerAddr.sin_addr)<<
" 接收的数据为:"<<RecvBuffer<<endl;
} 
}
return 0;
}
int main()
{
TestTCPCliCode();
//TestUDPCliCode();
return 0;
}

测试结果如下图所示:

如下图为TCP通信效果图:

如下图为UDP通信效果图:

时间: 2024-11-02 14:09:51

SOCKET通信程序源码的相关文章

串口屏(触摸屏)组态软件+多台51单片机MODBUS RTU多机串口通信程序源码

串口屏(触摸屏)组态软件+多台51单片机MODBUS RTU多机串口通信程序源码实现触摸屏(串口屏)与单片机的通讯,主要是解决通讯协议的问题.本文使用开放的Modbus通讯协议,以广州易显的HMImaker触摸屏作主机(Master),单片机作从机(Slaver).HMImaker触摸屏本身支持Modbus通讯协议,只要单片机按照Modbus协议进行收发数据,就可以进行通信了.触摸屏与单片机之间采用RS-485标准接口直接连接,与多台51单片机MODBUS RTU多机串口通信一.包括如下实例:二

java socket控制台版本聊天室程序源码下载

原文:java socket控制台版本聊天室程序源码下载 代码下载地址:http://www.zuidaima.com/share/1550463257578496.htm java socket控制台版本聊天室程序源码下载,学习的时候写的,适合学习java基础 java网络编程基础用 标签: java socket 控制台 聊天室 源码话题: 网络编程 java socket控制台版本聊天室程序源码下载,布布扣,bubuko.com

微信小程序-整理各种小程序源码和资料免费下载

微信小程序整理下载 [小程序源码]微信小程序-车源宝微信版 [小程序源码]小程序-微赞社区(论坛demo) [小程序源码]微信小程序-收支账单 [小程序工具]微信小程序-日历 [小程序源码]小程序-在线聊天功能 [小程序源码]微信小程序-大好商城(新增功能天气查询和2048游戏) [小程序源码]微信小程序-查询号码归属地 [小程序源码]微信小程序-备忘录2 [小程序源码]微信小程序-QQ音乐 [小程序源码]小程序-货币汇率 [小程序源码]微信小程序-大学图书馆 [小程序源码]小程序-积分商城 [

微信小程序源码下载(200多个)

微信小程序源码下载汇总,点击标题进入对应的微信小程序下载页面. 最新 demo源码(点击标题进入帖子下载) 描述 1 微信小程序 会议室预定小程序 微信小程序 会议室预定小程序**** 本内容被作者隐藏 **** 2 微信小程序-双人五子棋小游戏 微信小程序-双人五子棋小游戏**** 本内容被作者隐藏 **** 3 打卡签到小程序 用微信小程序实现的一个简单的打卡签到的小程序拒绝 4 微信小程序---左滑删除 微信小程序---左滑删除**** 本内容被作者隐藏 **** 5 一个借钱的记事本的微

微信小程序_微信小程序开发,小程序源码、案例、教程

原文地址:http://whosmall.com/?post=448 本文标签: 微信小程序 小程序源码案例 小程序项目 小程序源码 微信小程序教程 什么是微信小程序? 微信小程序是微信基于微信平台的一个应用发布平台,微信小程序app开发属于原生app组件提供js接口的开发方式,比混合是app的用户体验更好,仅次于原生应用. 不过微信小程序定位于小,要符合轻量易用无需下载,所以从体积上也是有限制,整个小程序应用体积不能超过1M. 微信小程序的应用场景? 微信小程序的应用场景适用于轻量应用,非强交

【小程序源码案例】微信小程序项目开发案例分享

作者:web小二本文标签: 微信小程序 小程序源码案例 小程序项目小程序的开发,并不是适合所有公司,我今天跟大家分享小程序方面的教程,主要是供大家学习使用.学习这种东西,有时候则是单纯的喜欢,没有任何目的,很单纯的为了好玩,记得很早之前学flash,没有想法,就是觉得好玩,纯娱乐爱好而已.到后来玩视频剪辑也是出于同样的原因,不图钱财名利,只是图自己个人爱好娱乐. 但是,学习,有时候则是需要有明确目的,特别是关系到自己吃饭问题的时候,你就需要非常有目的去学习,并且还需要制定好学习的计划与目标,希望

C#实现联通短信Sgip协议程序源码

此程序为中国联通Sgip协议程序接口,适合在中国联通申请了短信发送端口的公司使用. 短信群发已经成为现在软件系统.网络营销等必不可少的应用工具.可应用在短信验证.信息群发.游戏虚拟商品购买.事件提醒.送祝福等方面. 本程序功能包括: 1.支持中国联通Sgip1.2协议: 2.支持一般的短信发送.上行短信接收.状态报告: 3.支持长短信: 4.支持普通手机号和物联网卡: 5.全套C#.Net源码 程序适用于Sgip 1.2协议,可用.Net任何版本编译. DLL版:短信接口程序DLL源码,调用此D

不包含通信框架源码

源码 (不包含通信框架源码,通信框架源码请另行下载)上一篇文章写了如何通过TCP通信发送图片到客户端,有朋友问如何传送文件,本文将就如何发送文件进行探讨.对于比较小的文件,可以把文件转化成字节形式,用契约类包装一下,服务器收到后,再把字节转化成文件即可,这也是本文中实现的方式,这种方式的优点是比较简... 处理客户端发来的文件 private void IncomingUploadFile(PacketHeader header, Connection connection, FileWrapp

c# Ftp下载程序源码解析

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.IO; using System.Net; using System.Threading.Tasks; using System.Windows.Forms; n