您的位置:首页 > 理论基础 > 计算机网络

Socket TCP 简单聊天的实现

2012-09-17 15:27 423 查看
首先加入ws2_32.lib静态链接库:项目-属性-配置属性-链接器-输入-附加依赖项

或者在声明处加入#pragma comment(lib,"ws2_32.lib")

服务器端:

#include <iostream>
#include <winsock2.h>//2.0版本
#include <process.h>//_beginthreadex的头文件
#include <windows.h>//Sleep的头文件
using namespace std;
SOCKET serveSocket,clientSocket;
struct sockaddr_in addrSrv;
struct sockaddr_in addrCli;
char ip[20];
int InitSocket()//初始化套接字
{

WSADATA wsaData;
int err;
err = WSAStartup(MAKEWORD(2,2),&wsaData);
//该函数执行成功后返回0。
if (err != 0)
{
cout<<"加载套接字库失败"<<endl;
return 0;
}

addrSrv.sin_addr.s_addr=htonl(INADDR_ANY);
//计算机数据存储有两种字节优先顺序:高位字节优先和低位字节优先。
//Internet上数据以高位字节优先顺序在网络上传输,所以对于在内部是以低位字节优先方式存储数据的机器,
//在Internet上传输数据时就需要进行转换。
//多网卡的主机 //= inet_addr("127.0.0.1");//IP地址
addrSrv.sin_family=AF_INET;//协议
addrSrv.sin_port=htons(5020如果设置为0则随机选一个端口);//端口,

serveSocket = socket(AF_INET,SOCK_STREAM,0);
if (serveSocket == INVALID_SOCKET)
{
cout<<"创建套接字失败!"<<endl;
return 0;
}

err = bind(serveSocket,(sockaddr*)&addrSrv,sizeof(sockaddr));    //绑定端口和IP地址
if (err == SOCKET_ERROR)
{
closesocket(serveSocket);
cout<<"绑定失败"<<endl;
return 0;
}
}

void CleanFun()//清理套接字
{
closesocket(serveSocket);//执行成功就返回0,否则返回SOCKET_ERROR。
closesocket(clientSocket);//成功就返回0,否则返回SOCKET_ERROR。
WSACleanup();
}

UINT __stdcall ListenThread(LPVOID lParam)//监听线程
{
while(1)
{
int erro = listen(serveSocket,5);//开启监听成功返回0,失败返回SOCKET_ERROR.最大连接数1-5
if (erro == SOCKET_ERROR)
{
return 1;
//执行成功,则返回0;如果执行失败,则返回SOCKET_ERROR。
}
int len = sizeof(addrCli);
clientSocket = accept(serveSocket,(sockaddr*)&addrCli,&len);
if (clientSocket == INVALID_SOCKET)
{
return 1;
}
char * ipaddr = inet_ntoa(addrCli.sin_addr);
memcpy(ip,ipaddr,strlen(ipaddr));
cout<<"客户端 " << ip<<" 连接!"<<endl;
Sleep(100);
}
return 1;
}

//发送线程
UINT __stdcall SendThread(LPVOID lParam)
{
char sendBuf[65535];
ZeroMemory(sendBuf,sizeof(sendBuf));
while(1)
{
cin.getline(sendBuf,65535);
if(send(clientSocket,sendBuf,sizeof(sendBuf),0) == SOCKET_ERROR)
{
//套接字,缓冲区,缓冲区大小,0
//send把s的发送缓冲中的数据传到连接的另一端的,
//而是协议传的,send仅仅是把buf中的数据copy到s的发送缓冲区的剩余空间里
//如果send函数copy数据成功,就返回实际copy的字节数
cout<<"发送失败!";
return 0;
}
}
return 1;
}
//接收线程
UINT __stdcall RecvThread(LPVOID lParam)
{
while(1)
{
char szBuffer[65535];
ZeroMemory(szBuffer, sizeof(szBuffer));
int ret;
ret = recv(clientSocket,szBuffer,sizeof(szBuffer),0);
if(ret == 0)
{
cout<<"接收套接字失败"<<endl;
return 0;
}
if (ret > 0)
{
cout << ip <<":" << szBuffer << endl;
}
Sleep(100);
}

return 1;
}

int main(void)
{
ZeroMemory(ip,sizeof(ip));//ip初始化置0,API函数,相当于memset(ip,'\0',sizeof(ip));
InitSocket();
cout<<"服务器已启动:"<<endl;
_beginthreadex(NULL,NULL,ListenThread,NULL,NULL,NULL);
_beginthreadex(NULL,NULL,RecvThread,NULL,NULL,NULL);
_beginthreadex(NULL,NULL,SendThread,NULL,NULL,NULL);

while(1)
{
Sleep(100);//主界面循环,让线程有时间运行,并且Sleep,空循环会卡死
}
CleanFun();
return 1;

}


客户端:

#include<iostream>
#include<WinSock2.h>
#include <process.h>
#include <string>
#include <windows.h>
using namespace std;
SOCKET clientSocket;
sockaddr_in addrClient;
int InitSocket()
{
WSADATA wsaData;
int err;
err = WSAStartup(MAKEWORD(2,2),&wsaData);
if (err != 0)
{
cout<<"加载套接字库失败"<<endl;
return 0;
}

addrClient.sin_addr.s_addr = inet_addr("192.168.59.69");//=htonl(INADDR_ANY);//
addrClient.sin_family=AF_INET;
addrClient.sin_port=htons(5020);

clientSocket = socket(AF_INET,SOCK_STREAM,0);
if (clientSocket == INVALID_SOCKET)
{
cout<<"创建套接字失败!"<<endl;
return 0;
}
//客户端不需要绑定
if(connect(clientSocket,(sockaddr*)&addrClient,sizeof(addrClient)) == SOCKET_ERROR)
{
cout<<"连接服务器失败!";
//如果连接成功,connect返回0;如果失败则返回SOCKET_ERROR
return 1;
}
return 1;

}
void CleanFun()
{
closesocket(clientSocket);//成功就返回0,否则返回SOCKET_ERROR。
WSACleanup();//解除与Socket库的绑定并且释放Socket库所占用的系统资源
}

//发送线程
UINT __stdcall SendThread(LPVOID lParam)
{
char sendBuf[65535];
ZeroMemory(sendBuf,sizeof(sendBuf));
while(1)
{
cin.getline(sendBuf,65535);
if(send(clientSocket,sendBuf,sizeof(sendBuf),0) == SOCKET_ERROR)
{
cout<<"发送失败!";
return 0;
}
Sleep(50);
}
return 1;
}

//接收线程
UINT __stdcall RecvThread(LPVOID lParam)
{
while(1)
{
char szBuffer[65535];
ZeroMemory(szBuffer, sizeof(szBuffer));
int ret;
ret = recv(clientSocket,szBuffer,sizeof(szBuffer),0);
if(ret == 0)
{
cout<<"接收套接字失败"<<endl;
return 0;
}
if (ret > 0)
{
cout <<"服务器:"<< szBuffer << endl;
}
Sleep(50);
}

return 1;
}
int main(void)
{
InitSocket();
_beginthreadex(NULL,NULL,SendThread,NULL,NULL,NULL);
_beginthreadex(NULL,NULL,RecvThread,NULL,NULL,NULL);
while(1)
{
Sleep(500);
}
CleanFun();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: