基于Socket通信原理。原理请点击 Socket
目录:
1、添加库
编辑环境为CodeBlocks。首先添加要用的库。
具体操作为:Settings --> Compiler Settings --> Linker settings,然后点击Add,找到路径 E:\CodeBlocks\MinGW\lib\libws2_32.a (根据CB安装的路径不同自行改变),在右侧输入 -lws2_32,点击OK保存,重启CodeBlocks添加成功。
2、代码
Server.cpp
#include <stdio.h>
#include <Winsock2.h>
#pragma comment(lib, "WS2_32") // 链接到WS2_32.lib
using namespace std;
#include <fstream>
#include <string>
#include <iostream>
DWORD WINAPI RECVm(void *Param){
char sendBuf[50];//缓冲区
char recvBuf[50];//缓冲区
char username[50]={0}; // 用户名
SOCKET sockConn = *((SOCKET *)Param);
strcpy(sendBuf,"Join in chatroom success!You can start chatting...\n");
send(sockConn,sendBuf,strlen(sendBuf)+1,0);//将数据原样返回
recv(sockConn,recvBuf,50,0);
strcpy(username,recvBuf);
printf("%s has join in chatting room.\n",username);
while(1)
{
//接收
if(recv(sockConn,recvBuf,50,0)<=0){
printf("%s has exit!\n",username);
break;
}
if(recvBuf!=""){
printf("%s: %s\n",username,recvBuf);
}
strcpy(recvBuf,"");
}
closesocket(sockConn);
//closesocket(sockSrv);
return 0;
}
int main()
{
printf("Welcome to chatting room.....\n");
WORD wVersionRequested;//wVersionRequested 是我们要求使用的 WinSock 的版本。
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ){
return 0;}
if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 ){
WSACleanup( );
return 0;}
//创建套接字
SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);
//创建sockaddr_in结构体变量,绑定套接字
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");//通讯地址
addrSrv.sin_family=AF_INET; //sin_family必须为AF_INET,ipv4
addrSrv.sin_port=htons(6000); //端口号
//将套接字和 IP,端口 绑定
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
//进入监听状态,后台等待连接队列的最小限制值5
listen(sockSrv,5);
//接收
SOCKADDR_IN addrClient;
int len=sizeof(SOCKADDR);
while(1){
SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);
CreateThread(NULL,0,RECVm,&sockConn,0,NULL);
}
}
Client.cpp
#include <iostream>
#include <stdio.h>
#include <Winsock2.h>
#pragma comment(lib, "WS2_32")
using namespace std;
//
int main()
{
//初始化
WORD wVersionRequested; //版本
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 ); //主版号为1,副版号为1
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
return 0;
}
if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 )
{
WSACleanup( );
return 0;
}
//创建套接字
SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
//创建连接
connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
//发送
char yourname[50]={0};
printf("Please enter your username: ");
gets(yourname);
send(sockClient,yourname,strlen(yourname)+1,0);
char recvBuf[50];
recv(sockClient,recvBuf,50,0);
printf("Response: %s\n",recvBuf);
while(1){
printf("Enter Messages: ");
gets(yourname);
send(sockClient,yourname,strlen(yourname)+1,0);
//recv(sockClient,recvBuf,50,0);
//printf("Response: %s\n",recvBuf);
}
//char recvBuf[50];
//recv(sockClient,recvBuf,50,0);
//printf("Response: %s\n",recvBuf);
closesocket(sockClient);
WSACleanup();
}
3、运行程序
先运行Server程序,然后再运行Client程序,可运行多个Client程序,即一个服务端,多个客户端。
效果图:
我来评论一下
首先客户端退出后没做判断导致服务端死循环
第二客户端没做接收消息处理
第三无用代码写太多
你说的没错,我会找时间修改的?
客户端的BUG已经修改
test