/******************************A simple Linux Socket*******************************************
*
*************************************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <iostream.h>
#include <unistd.h>//close(socket)
#include <arpa/inet.h>//inet_ntoa()
// 服务器要监听的本地端口
#define MYPORT 4000
// 能够同时接受多少没有accept 的连接
#define BACKLOG 5
using namespace std;
string Compare(int rand_num, int num)
{
string str="good!";//用于返回比较结果 good表示相等.
if(rand_num==num)
return str;
rand_num < num ? (str="大了!"):(str="小了!");//比较
return str;
}
int main()
{
int rand_num=0; //产生的随机数
int cli_num=0;//用于接收用户数字
string send_str="";//用于发送/返回比较的结果
/* 在sock_fd 上进行监听,new_fd 接受新的连接 */
int sockfd, new_fd ;
/* 自己的地址信息 */
struct sockaddr_in my_addr;
/* 连接者的地址信息*/
struct sockaddr_in their_addr;
// int sin_size;
socklen_t sin_size;
/* 如果调用socket() 出错,则返回 */
cout<<"Creating socket..."<<endl;
if ((sockfd =socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
/* 输出错误提示并退出 */
perror("socket error");
cout<<errno<<endl;
exit(1);
}
cout<<"[ok]"<<endl;
/* 主机字节顺序 */
my_addr.sin_family = AF_INET;
/* 网络字节顺序,短整型 */
my_addr.sin_port = htons(MYPORT);
/* 将运行程序机器的IP 填充入s_addr */
my_addr.sin_addr.s_addr = INADDR_ANY;
/* 将此结构的其余空间清零 */
bzero(&(my_addr.sin_zero), 8);
cout<<"binding..."<<endl;
if (bind(sockfd, (struct sockaddr *)&my_addr,sizeof(struct sockaddr)) == -1)
{
/* 如果调用bind()失败,则给出错误提示,退出 */
perror("bind error");
cout<<errno<<endl;
exit(1);
}
cout<<"[ok]"<<endl;
if (listen(sockfd, BACKLOG) == -1)
{
/* 如果调用listen 失败,则给出错误提示,退出 */
perror("listen error");
cout<<errno<<endl;
exit(1);
}
srand(time(NULL));
rand_num=(int)(32766.0*rand()/(RAND_MAX+1.0)+1.0);//产生随机数1-32767
cout<<"rand_num is "<<rand_num<<endl;
cout<<"Listening..."<<endl;
while(1)
{
/* 这里是主accept()循环 */
//sin_size = sizeof(struct sockaddr_in);
sin_size= sizeof(their_addr);
/* 这里将建立一个子套接字来和刚刚建立的套接字进行通讯 */
if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1)
{
/* 如果调用accept()出现错误,则给出错误提示,进入下一个循环 */
perror("accept error ");
cout<<errno<<endl;
continue;
}
/* 服务器给出出现连接的信息 */
printf("server: Got connection from %s/n", inet_ntoa(their_addr.sin_addr));
send(new_fd, "Please input a number:",36 , 0);
if(recv(new_fd,&cli_num,sizeof(cli_num),0)==-1)//接收数据
{
perror("recv error");
cout<<errno<<endl;
exit(1);
}
cout<<"Received a number. num="<<cli_num<<endl;
send_str=Compare(rand_num,cli_num);
if (send(new_fd, &send_str, sizeof(send_str), 0) == -1)//返回结果
{
/* 如果错误,则给出错误提示,然后关闭这个新连接,退出 */
perror("send error");
cout<<errno<<endl;
close(new_fd);
exit(1);
}
/* 关闭new_fd 代表的这个套接字连接 */
close(new_fd);
}
/* 等待所有的子进程都退出 */
// while(waitpid(-1,NULL,WNOHANG) > 0);
return 0;
}