基于字符界面的聊天程序1.0

编译器:Vs2013 community (VC6.0 运行亦可,但要注意函数的更新,如更安全的函数,etc)

服务器端程序流程:

1、加载套接字库

2、创建套接字(socket)。

3、将套接字绑定到一个本地地址和端口上(bind)。

4、将套接字设为监听模式,准备接收客户请求(listen)。

5、等待客户请求到来;当请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept)。

6、用返回的套接字和客户端进行通信(send/recv)。

7、返回,等待另一客户请求。

8、关闭套接字。

 

客户端程序流程:

1、加载套接字库

2、创建套接字(socket)。

3、向服务器发出连接请求(connect)。

4、和服务器端进行通信(send/recv)。

5、关闭套接字。


服务器端代码:

#include <Winsock2.h>
#include <stdio.h>


void main()
{
/***********加载套接字库2.2版本************/
WORD wVersionRequested;
WSADATA wsaData;
int err;


wVersionRequested = MAKEWORD(2, 2);


err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0) {
return;
}


if (LOBYTE(wsaData.wVersion) != 2 ||
HIBYTE(wsaData.wVersion) != 2) {
WSACleanup();
return;
}


/******************创建套接字*******************/
SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0);


/*****************绑定套接字********************/
SOCKADDR_IN addrSrv;       //定义 地址结构体 变量addrSrv
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(6800);


bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));


/****************设置监听模式********************/
listen(sockSrv, 5);//参数2:等待连接队列的最大值


char recvBuf[100];
char sendBuf[100];
char tempBuf[200];
/***********等待客户连接请求到来,并接受**********/
SOCKADDR_IN addrClient;
int len = sizeof(SOCKADDR);
SOCKET sockConn = accept(sockSrv, (SOCKADDR*)&addrClient, &len);
while (1)
{
/**********进行通信**********/
recv(sockConn, recvBuf, 100, 0); //服务端先接收数据
if ('~' == recvBuf[0])//如果接受的数据第一个字符是 ~ 则退出!!!
{
send(sockConn, "~", strlen("~") + 1, 0);
printf("Chat end!\n");
break;
}
sprintf(tempBuf, "%s say %s.", inet_ntoa(addrClient.sin_addr), recvBuf);//将得到的数据格式化 放到tempBuf中
printf("%s\n", tempBuf);//输出客户端信息

printf("Server say: ");
gets(sendBuf);//从标准输入流中获取一行数据,回车后放入sendBuf中
send(sockConn, sendBuf, strlen(sendBuf) + 1, 0);
}
closesocket(sockSrv);//关闭套接字
WSACleanup();//终止对套接字库的使用
}


客户端代码:

#include <Winsock2.h>
#include <stdio.h>


void main()
{
/***********加载套接字库2.2版本************/
WORD wVersionRequested;
WSADATA wsaData;
int err;


wVersionRequested = MAKEWORD(2, 2);


err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0) {
return;
}


if (LOBYTE(wsaData.wVersion) != 2 ||
HIBYTE(wsaData.wVersion) != 2) {
WSACleanup();
return;
}


/******************创建套接字*******************/
SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);


/************向服务器发出connect请求**************/
SOCKADDR_IN addrSrv;
// addrSrv.sin_addr.S_un.S_addr = inet_addr("192.168.1.111");
addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");//将点分十进制转换成ulong类型
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(6800);


connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));


char recvBuf[100];
char sendBuf[100];
char tempBuf[200];
/************和服务器进行通信**********/
int len = sizeof(SOCKADDR);
while (1)
{
printf("Client say: ");
gets(sendBuf);//通过键盘得到一行数据
send(sockClient, sendBuf, strlen(sendBuf) + 1, 0);//客户端发送数据
recv(sockClient, recvBuf, 100, 0);//接收数据
if ('~' == recvBuf[0])
{
send(sockClient, "~", strlen("~") + 1, 0);
printf("Chat end!\n");
break;
}
sprintf(tempBuf, "%s say %s.", inet_ntoa(addrSrv.sin_addr), recvBuf);
printf("%s\n", tempBuf);
}
closesocket(sockClient);//关闭套接字
WSACleanup();//终止对套接字库的使用
}


注意事项:(我走过的弯路!!!)

1、在服务、客户两端,project->设置->linker,增加ws2_32.lib库

2、可以取消SDL检查(根据编译器不同自行选择)

3、服务端用于接收客户端数据的套接字sockConn要在while循环外

4、用于监听的套接字sockSrv与接收数据的套接字sockConn不同


运行效果图:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值