Linux开发|一步一步学习Unix编程[2]——迭代服务器
【Linux开发|一步一步学习Unix编程[2]——迭代服务器】转载请注明t1234xy4原创:http://blog.csdn.net/t1234xy4/article/details/51925011
1、迭代服务器 所谓迭代服务器就是处理完一个客服端请求后,接着再处理第二个客服端请求,如果没有请求服务器将阻塞在accept处,直到有请求传来。
2、自定义头文件
在编代码前,需要先介绍自定义的一个头文件:MyIncludding.h
/*
* MyIncluding.h
*
*Created on: Jul 11, 2016
*Author: ubuntu
*/#ifndef HEADER_MYINCLUDING_H_
#define HEADER_MYINCLUDING_H_#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include #defineMAXLINE 1024
#defineFIFO_MODE (S_IRUSR | S_IWUSR | S_IRGRP |S_IROTH)#define SERV_PORT9877
#define SAstruct sockaddr
#define LISTENQ1024#endif /* HEADER_MYINCLUDING_H_ */
此处定义了服务器的监听端口SERV_PORT = 9877,服务器将使用这个端口监听。 同时定义了服务器监听的客户端请求的总个数 LISTENQ。LISTENQ包括了服务器端已建立连接的队列和未建立连接队列的总和。 已建立链接队列中保存了客户端与服务器端完成了TCP三路握手,这些链接处于ESTABLISHED状态,但没有服务器还没有accept此链接。 未建立连接队列中保存未客户端与服务器端还没有建立连接,客户的连接请求刚刚到达服务器,也就是三路握手的第一步。此时链接处于SYN_RCVD状态。如果三路握手正常完成将插入到已连接队列后。如果链接进入为建立连接队列超过一个RTT(往返时间)则被丢弃(因为重传机制,如果不丢弃将可能与该客户端建立两次链接或者更多)。
3、服务器端源码
/*
* ServiceFork.cpp
*
*Created on: Jul 15, 2016
*Author: ubuntu
*/
#include
#include "MyIncluding.h"using namespace std;
char serv_ip[16] = "172.25.9.94";
//本地IP地址int main(int argc,char** argv)
{
int listenfd,connfd;
pid_t childpid;
struct sockaddr_in cliaddr,servaddr;
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
inet_pton(AF_INET,serv_ip,&servaddr.sin_addr);
servaddr.sin_port = htons(SERV_PORT);
listenfd = socket(AF_INET,SOCK_STREAM,0);
int nbind = bind(listenfd,(SA *)&servaddr,sizeof(servaddr));
int nlisten = listen(listenfd,LISTENQ);
while(1)
{
socklen_t cliaddrlen= sizeof(cliaddr);
connfd = accept(listenfd,(SA *)&cliaddr,&cliaddrlen);
if(connfd<0)
cout <<"accept error!"< 0 )
cout<< "receive MSG:"<
此服务器端很简单,就与客户端建立连接,然后接受客户端传来的消息打印出来。 那么客户端应该做的事是与服务器建立连接,然后传一条消息过去。
4、客户端代码 为了便于扩展,我将客户端封装为一个SimClient类: SimClient.h
/*
* SimClient.h
*
*Created on: Jul 13, 2016
*Author: ubuntu
*/#ifndef SIMCLIENT_H_
#define SIMCLIENT_H_#include "MyIncluding.h"
#include "IOoperater.h"
#include
#include using namespace std;
class SimClient {public:
SimClient();
bool virtual connectServer();
virtual bool run();
void setClientId(int i){_clientId = i ;
}
virtual bool stopRunning();
virtual bool reRun();
virtual ~SimClient();
protected:
int sockfd;
char* buf;
struct sockaddr_in serviceaddr;
int _clientId;
};
#endif /* SIMCLIENT_H_ */
SimClient.cpp
/*
* SimClient.cpp
*
*Created on: Jul 13, 2016
*Author: ubuntu
*/#include "SimClient.h"SimClient::SimClient():sockfd(-1),_clientId(-1){
// TODO Auto-generated constructor stub
buf = new char[1];
strcpy(buf,"\0");
}bool SimClient::connectServer()
{
sockfd = socket(AF_INET,SOCK_STREAM,0);
bzero(&serviceaddr,sizeof(serviceaddr));
serviceaddr.sin_family = AF_INET;
char mySERV_IP[16] ="172.25.9.94";
inet_pton(AF_INET,mySERV_IP,&serviceaddr.sin_addr);
//serviceaddr.sin_addr = htonl(SERV_IP);
serviceaddr.sin_port = htons(SERV_PORT);
int connectret;
connectret = connect(sockfd,(SA *)&serviceaddr,sizeof(serviceaddr));
if(connectret<0)
{
cout << "connection error,errno="<
客户端调用入口:
//============================================================================
// Name: SimClient.cpp
// Author: Tian
// Version:
// Copyright: Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================#include
#include "SimClient.h"
using namespace std;
int main() {
cout << "!!!!!!thread Test is running!!!!!!" << endl;
sleep(1);
SimClient *thread = new SimClient;
thread->setThreadId(i);
if (!thread->connectServer())
{
cout << "thread "<< i << "failed!"<getThreadId()<run();
cout << thread->getThreadId() <<" shutdown !";
delete thread;
return 0;
}
总结: 服务端:socket()->bind()->listen()->accept()(阻塞)->read() 客户端:socket()->connect()->write() 结果是服务器端收到客服端的Id以及时间信息。
推荐阅读
- 深入理解Go之generate
- 标签、语法规范、内联框架、超链接、CSS的编写位置、CSS语法、开发工具、块和内联、常用选择器、后代元素选择器、伪类、伪元素。
- Linux下面如何查看tomcat已经使用多少线程
- 也许第一步很难,但跨过去就好了
- Beego打包部署到Linux
- 我的软件测试开发工程师书单
- Linux|109 个实用 shell 脚本
- echart|echart 双轴图开发
- NPDP拆书(三)(新产品开发战略(经营与创新战略))
- 高度自律等于成功的第一步