本程序实现的功能:完成学生信息注册功能,即把学生的信息存放到服务器。
(1)服务器端server.cpp文件内容
#include <stdio.h>
#include <arpa/inet.h>
#include <string.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#define MYPORT 6013
#define SERADDR "192.168.1.141" //这里要设置为服务器的IP地址
#define BLEN 100
#define STAT_OK 0
#define STAT_ERR 1
#define CMD_REGISTER 1
typedef struct FORMAT
{
char name[20];
int age;
int cmd;
int stat;
}info;
char recvbuf[100];
int main(void)
{
int sockfd=-1;
int ret=-1;
int clifd=-1;
socklen_t len=0;
struct sockaddr_in seraddr={0};//也可以使用memset函数进行初始化
struct sockaddr_in clientaddr={0};
//第一步:socket函数,获取网络连接的文件描述符
sockfd=socket(AF_INET,SOCK_STREAM,0);
if(-1==sockfd)
{
perror("socket error:");
return -1;
}
printf("socket success!socket=%d.\n",sockfd);
//第二步:bind函数,绑定sockfd与服务器的ip地址、端口号
//填充seraddr这个结构体
seraddr.sin_family=AF_INET;//定义ip类型,IPV6还是IPV4
seraddr.sin_port=htons(MYPORT);
seraddr.sin_addr.s_addr=inet_addr(SERADDR);
ret=bind(sockfd,(const struct sockaddr*)&seraddr,sizeof(seraddr));//类型不一样,会警告
if(ret==-1)
{
perror("bind error:");//函数本身有错误号时可以用perror来显示错误信息
}
printf("bind success!\n");
//第三步:listen函数,监听服务器的当前端口(其他端口不监听)
ret=listen(sockfd,BLEN);//第二个参数是服务器允许的队列长度,比如最多100号
if(ret==-1)
{
perror("listen error:");
}
printf("listen success!\n");
//第四步:accept函数,阻塞等待用户连接
//注意accept返回值是网络文件描述符,
//和sockfd不同,它才是真正的用于发送数据的fd,而sockfd只是用于侦听的。
clifd=accept(sockfd,(struct sockaddr*)&clientaddr,&len);
printf("用户连接成功!\n");
/*
while(1)
{
//第五步:recv函数,服务器开始接收数据
ret=recv(clifd,recvbuf,sizeof(recvbuf),0);
printf("client发送的内容是:%s\n",recvbuf);
memset(recvbuf,0,sizeof(recvbuf));
//第六步:服务器解释数据包
//第七步:回复客户端OK
ret=send(clifd,"OK",2,0);
}
*/
while(1)
{
info st;
ret=recv(clifd,&st,sizeof(recvbuf),0);
if(CMD_REGISTER==st.cmd)
{
printf("用户要注册学生信息\n");
printf("姓名:%s,年龄:%d\n",st.name,st.age);
st.stat=STAT_OK;
ret=send(clifd,&st,sizeof(info),0);
}
}
return 0;
}
(2)客户端client.cpp文件内容
#include<stdio.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<arpa/inet.h>
#include<string.h>
#define SERPORT 6013
#define SERADDR "192.168.1.141"//要设置为服务器的IP地址
#define CMD_REGISTER 1
#define STAT_OK 0
#define STAT_ERR 1
typedef struct FORMAT
{
char name[20];
int age;
int cmd;
int stat;
}info;
char sendbuf[100];
char recvbuf[100];
int main(void)
{
//第一步:socket函数,获取网络连接的文件描述符
int sockfd=-1;
int ret=-1;
struct sockaddr_in seraddr={0};
sockfd=socket(AF_INET,SOCK_STREAM,0);
if(-1==sockfd)
{
perror("socket error:");
return -1;
}
printf("socket success.socket=%d.\n",sockfd);
//第二步:connect函数,连接服务器
seraddr.sin_family=AF_INET;//定义ip类型,IPV4还是IPV6
seraddr.sin_port=htons(SERPORT);
seraddr.sin_addr.s_addr=inet_addr(SERADDR);
ret=connect(sockfd,(const struct sockaddr*)&seraddr,sizeof(seraddr));
printf("连接成功\n");
/*
while(1)
{
//第三步:send函数,客户端给服务器发送信息
printf("请输入你想发给服务器的内容:\n");
scanf("%s",sendbuf);
ret=send(sockfd,sendbuf,strlen(sendbuff),0);
//第四步:客户端接收服务器端的回复
memset(recvbuf,0,sizeof(recvbuf));
ret=recv(sockfd,recvbuf,sizeof(recvbuf),0);
printf("服务器回复内容是:%s\n",recvbuf);
//第五步:客户端解释服务器的回复,再做下一步定夺
}
*/
info st1;
while(1)
{
printf("\n请输入学生姓名:\n");
scanf("%s",st1.name);
printf("\n请输入学生年龄:\n");
scanf("%d",&st1.age);
st1.cmd=CMD_REGISTER;
ret=send(sockfd,&st1,sizeof(info),0);
//第四步:客户端接收服务器端的回复
memset(&st1,0,sizeof(st1));
ret=recv(sockfd,&st1,sizeof(st1),0);
if(STAT_OK==st1.stat)
{
printf("注册学生信息成功!");
}
else
printf("注册学生信息失败!");
}
return 0;
}