计算机网络课程设计——网络聊天程序的设计与实现
程序员文章站
2024-02-12 10:36:10
...
服务器的代码
/*
* 服务器端 Server.c
*
*/
#pragma comment(lib,"ws2_32")
#include <winsock2.h>
#include <stdio.h>
#include <string.h>
#define BUFFSIZE 1024
int main(int argc, char**argv)
{
int Ret; //赋予初始化之后的要赋予的值
WSADATA wsaData; //初始化
SOCKET ListeningSocket; //监听客户机的套接字
SOCKET NewConnection; //建立连接的套接字
SOCKADDR_IN ServerAddr; //服务器端结构体
SOCKADDR_IN ClientAddr; //客户机端结构体
int ClientAddrLen = sizeof(ClientAddr); //计算客户机断结构体的长度
unsigned short Port = 5000; //和客户机建立的端口,客户机也有一个端口号,两个端口号相同时才会建立连接,TCP/IP的端口号的范围在0-65535
char sendData[BUFFSIZE]; //传送的数据
char recvData[BUFFSIZE]; //接受的数据
//第一步、初始化WinSock,调用WSAStarup接口函数就可以
if((Ret = WSAStartup(MAKEWORD(2,2), &wsaData)) != 0)
{
printf("WSASTARTUP_ERROR: %d\n", Ret);
return 0;
}
//第二步、创建一个套接字来监听客户机连接,套接字socket包含了两个信息,一个是IP地址,一个是Port端口号,使用
//这两个信息,就可以确定网路中的任何一个通讯节点。
//socket三个参数的含义、第一个参数指定Socket类型(流式、数据报套接字)、第三个套接字是与特定的地址家族相关的协议(若指定为0,系统会自动选择一个合适的协议)
if((ListeningSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)//INVALID_SOCKET意思是无效套接字
{
printf("SOCKET_ERROR: %d\n", INVALID_SOCKET);
return 0;
}
/*
*第三步、 填充SOCKADDR_IN结构,这个结构将告知bind我们想要在5150端口监听所有接口上的连接
*/
ServerAddr.sin_family = AF_INET; //sin_family字段必须设置为AF_INET,这是告诉WinSock使用的是IP地址族
ServerAddr.sin_port = htons(Port); //将端口变量从主机字节顺序转换位网络字节顺序,必须要设置
//IP地址(long)和port端口(short),转换成网络字节后才能用bind()函数绑定
ServerAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); //用来通讯的IP地址
//第四步、使用bind将这个地址信息和套接字绑定起来,包含了需要建立连接的本地的地址,包括地址组、IP和端口信息
//int bind(SOCKET s,const stuct sockaddr FAR* name,int namelen)
if(bind(ListeningSocket, (SOCKADDR *)&ServerAddr, sizeof(ServerAddr)) == SOCKET_ERROR)
{
printf("BIND_ERROR: %d\n", SOCKET_ERROR);
return 0;
}
//第五步、监听客户机连接。这里使用5个backlog
if(listen(ListeningSocket, 5) == SOCKET_ERROR)
{
printf("LISTEN_ERROR: %d\n", SOCKET_ERROR);
return 0;
}
//第六步、连接到达时,接受连接
printf("正在接受连接...");
if((NewConnection = accept(ListeningSocket, (SOCKADDR *)&ClientAddr, &ClientAddrLen)) == INVALID_SOCKET)
{
printf("ACCPET_ERROR: %d\n", INVALID_SOCKET);
closesocket(ListeningSocket);
return 0;
}
printf("检测到一个连接: %s 端口:%d\n", inet_ntoa(ClientAddr.sin_addr), ntohs(ClientAddr.sin_port));
//第七步、聊天
while(true)
{
//接收数据
Ret = recv(NewConnection, recvData, BUFFSIZE, 0);
if(Ret > 0)
printf("Client对你说: %s\n", recvData);
else if(Ret < 0)
printf("RECV_ERROR: %d\n", SOCKET_ERROR);
else
{
printf("对方退出程序,聊天结束!");
break;
}
//发送数据
printf("\nServer说:");
scanf("%s", sendData);
if(strcmp(sendData, "quit") == 0) //退出
break;
if(send(NewConnection, sendData, BUFFSIZE, 0) == SOCKET_ERROR)
{
printf("消息发送失败!\n");
break;
}
}
//第八步、从容关闭
shutdown(NewConnection, SD_BOTH);
//完成新接受的连接后,用closesocket API关闭这些套接字
closesocket(NewConnection);
closesocket(ListeningSocket);
//应用程序完成对接的处理后,调用WSACleanup
if(WSACleanup() == SOCKET_ERROR)
{
printf("WSACLEANUP_ERROR: %d\n", WSAGetLastError());
return 0;
}
system("pause");
return 0;
}
客户端代码
/*
* 客户端 Client.c
*
*/
#include<iostream>
#include<WinSock2.h>
#pragma comment(lib,"ws2_32.lib")
using namespace std;
#define BUFFSIZE 1024
int main()
{
int Ret; //赋予初始化之后的要赋予的值
char sendData[BUFFSIZE];//定义发送缓冲区和接受缓冲区
char recvData[BUFFSIZE];
SOCKET s_server;//定义服务端套接字,接受请求套接字
SOCKADDR_IN server_addr;//服务端地址客户端地址
//初始化套接字库
WORD w_req=MAKEWORD(2,2);//版本号
WSADATA wsadata;
int err;
err = WSAStartup(w_req,&wsadata);
if(err!=0)
{
cout<<"初始化套接字库fail"<<endl;
}
else
{
cout<<"初始化套接字库success"<<endl;
}
//填充服务端信息
server_addr.sin_family=AF_INET;
server_addr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
server_addr.sin_port=htons(5000);
//创建套接字
s_server=socket(AF_INET,SOCK_STREAM,0);
//建立连接
if(connect(s_server,(SOCKADDR *)&server_addr,sizeof(SOCKADDR))==SOCKET_ERROR)
{
cout<<"CONNECT_ERROR : "<<SOCKET_ERROR<<endl;
return 0;
}
else
{
cout<<"服务器连接成功!"<<endl;
}
//发送,接收数据
while(true){
//发送数据
cout<<'\n'<<"Client说:";
cin>>sendData;
if(strcmp(sendData,"quit") == 0)
{
break;
}
if(send(s_server,sendData,BUFFSIZE,0) == SOCKET_ERROR)
{
cout<<"消息发送失败"<<endl;
break;
}
//接收数据
Ret = recv(s_server,recvData,BUFFSIZE,0);
if(Ret < 0)
{
cout<<"RECV_ERROR"<<SOCKET_ERROR<<endl;
break;
}
else if(Ret == 0)
{
cout<<"对方退出聊天程序,聊天结束"<<endl;
break;
}
else
{
cout<<"Server对你说:"<<recvData<<endl;
}
}
//关闭套接字
closesocket(s_server);
//释放DLL资源
WSACleanup();
return 0;
}
上一篇: ubuntu 配置静态IP地址