在工作中,用到各种框架,基本都是将底层的通讯给封装好了,于是想自己动动手,光看看老是忘记。一下例子为使用socket tcp实现的一个简单的例子,即是一个echo模型的简单聊天室服务,服务端启动后,等待客户端连接,如果客户端连接进来,则创建一个子进程来处理客户端的io。注意:本例子单纯的使用tcp长连接,当连接数量大时,服务器会宕机,这个时候应使用更高效的epoll来实现。直接上代码如下:
本例子只有2个文件socketserver.cpp 和socketclient.cpp,sockt相关的一些函数可以参考其它博文,这里暂不赘述。
socket..cpp文件:
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#define PORT 8010
int main (int argc, char **argv)
{
int server_fd, connect_fd;
sockaddr_in serveraddr;
server_fd = socket(AF_INET, SOCK_STREAM, 0);
if(server_fd == -1)
{
printf("create socket err:%s,errno:%d\n",strerror(errno),errno);
return 1;
}
memset(&serveraddr, 0, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
serveraddr.sin_port = htons(PORT);
int result = bind(server_fd, (struct sockaddr*) &serveraddr, sizeof(serveraddr));
if(result == -1)
{
printf("bind socket err:%s,errno:%d\n",strerror(errno),errno);
return 1;
}
result = listen(server_fd, 10);
if(result == -1)
{
printf("listen socket err:%s,errno:%d\n",strerror(errno),errno);
return 1;
}
while(true)
{
printf("==server is ok, ready for accept:\n");
connect_fd = accept(server_fd, (struct sockaddr*) NULL,NULL);
if(connect_fd == -1)
{
printf("connect err:%s,errno:%d",strerror(errno),errno);
continue;
}
printf("==accept fd:%d\n",connect_fd);
int pid = fork();
if(pid == 0)
{
char buff[4096] = "";
while(true)
{
int recvlen = recv(connect_fd, buff, sizeof(buff), 0);
if(recvlen == 0 || strcmp(buff,"quit") == 0)
{
break;
}
buff[recvlen] = '\0';
printf("==recv msg from client msg:%s,fd:%d\n", buff,connect_fd);
int sendresult = send(connect_fd, buff, strlen(buff), 0);
if(sendresult == -1){
break;
}
}
close(connect_fd);
}
close(connect_fd);
}
close(server_fd);
return 0;
}
编译:g++ -o server.out socktserver.cpp
socketclient.cpp文件:
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <iostream>
#include <arpa/inet.h>
#define STRIP "127.0.0.1"
#define PORT 8010
int main(int argc, char **argv)
{
int socketfd;
sockaddr_in serveraddr;
socketfd = socket(AF_INET, SOCK_STREAM, 0);
if(socketfd < 0)
{
printf("create socket err:%s,errno:%d\n",strerror(errno),errno);
return 1;
}
memset(&serveraddr, 0, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(PORT);
if(inet_pton(AF_INET, STRIP, &serveraddr.sin_addr) <= 0){
printf("inet_pton err:%s,errno:%d\n",strerror(errno),errno);
return 1;
}
int result = connect(socketfd,(struct sockaddr*) &serveraddr, sizeof(serveraddr));
if(result< 0){
printf("connect socket err:%s,errno:%d\n",strerror(errno),errno);
return 1;
}
char buff[1024];
char recvbuff[1024];
while(std::cin >> buff)
{
printf("==send msg to server:%s\n",buff);
result = send(socketfd, buff,sizeof(buff),0);
if(result <= 0){
printf("send msg:%s err:%s,errno:%d",buff,strerror(errno),errno);
break;
}
int recvlen = recv(socketfd, recvbuff, sizeof(recvbuff), 0);
if(recvlen <= 0)
{
printf("recv err:%s,errno:%d",strerror(errno),errno);
break;
}
recvbuff[recvlen] = '\0';
printf("==recv msg from server:%s\n",recvbuff);
}
close(socketfd);
return 0;
}
编译:g++ -o client.out socketclient.cpp