1、服务端
//socket_sv.c
#include
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char* argv){
//1.creat linsten socket
int lfd = socket(AF_INET, SOCK_STREAM,0);
if (lfd == -1)
{
perror("socket");
exit(0);
}
//2.bind lfd to local ip address and port
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(10000);
int ret = bind(lfd,(struct sockaddr *)&addr,sizeof(addr));
if (ret == -1){
perror("bind");
exit(0);
}
//3,listen
ret = listen(lfd, 128);
if (ret == -1)
{
perror("listen");
exit(0);
}
//3.accept and block wait client connect
struct sockaddr_in cliaddr;
int addrlen = sizeof(cliaddr);
int cfd = accept(lfd, (struct sockaddr *)&cliaddr,&addrlen);
if (cfd == -1)
{
perror("accept");
exit(0);
}
//4.print client information
char ip[24] = {0};
printf("client ip addres: %s, port: %d\n",
inet_ntop(AF_INET,&cliaddr.sin_addr.s_addr,ip,sizeof(ip)),ntohs(cliaddr.sin_port));
//5.recv and send message with client
while (1)
{
char buf[1024];
memset(buf,0 ,sizeof(buf));
int len = read(cfd, buf,sizeof(buf));
if (len > 0)
{
printf("recv from client: %s\n",buf);
write(cfd, buf, len);
}else if(len == 0){
printf("client disconnect...\n");
break;
}else{
perror("read");
break;
}
}
close(cfd);
close(lfd);
return 0;
}
2、客户端
#include
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char* argv){
//1.creat communcation socket
int fd = socket(AF_INET, SOCK_STREAM,0);
if (fd == -1)
{
perror("socket");
exit(0);
}
//2.connect server
struct sockaddr_in addr;
addr.sin_family = AF_INET;
inet_pton(AF_INET,"localhost",&addr.sin_addr.s_addr);
addr.sin_port = htons(10000);
int ret = connect(fd,(struct sockaddr *)&addr,sizeof(addr));
if (ret == -1){
perror("connect");
exit(0);
}
//3. communication with server
int number = 0;
while (1)
{
char buf[1024];
sprintf(buf, "hello socket...%d\n",number++);
write(fd, buf,strlen(buf)+ 1);
// recv form server
memset(buf,0,sizeof(buf));
int len = read(fd, buf, sizeof(buf));
if (len > 0)
{
printf("recv from server: %s\n",buf);
}else if(len == 0){
printf("server disconnect...\n");
break;
}else{
perror("read");
break;
}
sleep(1);
}
close(fd);
return 0;
}
3、多进程实现服务端并发
//socket_sv1.c
//mutiple process concurrency server
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
void callback(int num){
while(1){
pid_t pid = waitpid(-1, NULL, WNOHANG);
if (pid <= 0)
{
printf("chind process is running or had been collect.\n");
break;
}
printf("child die, pid = %d\n", pid);
}
}
int childWork(int cfd){
char buf[1024];
memset(buf, 0, sizeof(buf));
int len = read(cfd ,buf,sizeof(buf));
if (len > 0)
{
printf("recv form cliet: %s\n", buf);
write(cfd, buf,len);
}else if(len == 0){
printf("client disconnect...\n");
}else{
perror("read");
}
return len;
}
int main(int argc, char* argv){
//1.creat linsten socket
int lfd = socket(AF_INET, SOCK_STREAM,0);
if (lfd == -1)
{
perror("socket");
exit(0);
}
//2.bind lfd to local ip address and port
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(10000);
int ret = bind(lfd,(struct sockaddr *)&addr,sizeof(addr));
if (ret == -1){
perror("bind");
exit(0);
}
//3,listen
ret = listen(lfd, 128);
if (ret == -1)
{
perror("listen");
exit(0);
}
//regesist signal
struct sigaction act;
act.sa_flags = 0;
act.sa_handler = callback;
sigemptyset(&act.sa_mask);
sigaction(SIGCHLD,&act, NULL);
while (1)
{
//block and wait client connect
struct sockaddr_in cliaddr;
int clilen = sizeof(cliaddr);
int cfd = accept(lfd, (struct sockaddr* )&cliaddr, &clilen);
if (cfd == -1){
if(errno ==EINTR){
//accept interupp by signal, relese block, return -1
//call one times again
continue;
}
perror("accept");
exit(0);
}
//print client information
char ip[24] = {0};
printf("client ip addres: %s, port: %d\n",
inet_ntop(AF_INET,&cliaddr.sin_addr.s_addr,ip,sizeof(ip)),ntohs(cliaddr.sin_port));
//creat child process connect
pid_t pid = fork();
if (pid == 0){
close(lfd);
while (1)
{
int ret = childWork(cfd);
if (ret <= 0){
break;
}
}
close(cfd);
exit(0);
}else if(pid > 0){
close(cfd);
}
}
return 0;
}
4、多线程实现服务端并发
//socket_sv2.c
//pthread concurrency server
#include
#include
#include
#include
#include
#include
#include
#include
#include
struct SockInfo{
int fd;
pthread_t tid;
struct sockaddr_in addr;
};
struct SockInfo infos[128];
void *working(void* arg){
while (1)
{
struct SockInfo* info = (struct SocInfo*) arg;
// recv data
char buf[1024];
int ret = read(info->fd,buf,sizeof(buf));
if(ret == 0){
printf("client disconnect...\n");
break;
}else if(ret == -1){
printf("recv data fail...\n");
info->fd = -1;
break;
}else{
write(info->fd,buf,strlen(buf) +1);
}
}
return NULL;
}
int main(int argc, char* argv){
//1.creat linsten socket
int fd = socket(AF_INET, SOCK_STREAM,0);
if (fd == -1)
{
perror("socket");
exit(0);
}
//2.bind lfd to local ip address and port
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(10000);
int ret = bind(fd,(struct sockaddr *)&addr,sizeof(addr));
if (ret == -1){
perror("bind");
exit(0);
}
//3,listen
ret = listen(fd, 128);
if (ret == -1)
{
perror("listen");
exit(0);
}
//4.wait client connect request
int len = sizeof(struct sockaddr);
// init
int max = sizeof(infos)/sizeof(infos[0]);
for (int i = 0; i < max; i++)
{
bzero(&infos[i],sizeof(infos[0]));
infos[i].fd = -1;
infos[i].tid = -1;
}
//parent listen and child communicate
while (1)
{
struct SockInfo* pinfo;
for (int i = 0; i < max; i++)
{
if (infos[i].fd == -1){
pinfo = &infos[i];
break;
}
if(i == max -1){
sleep(1);
i--;
}
}
int connfd = accept(fd, (struct sockaddr *)&pinfo->addr,&len);
printf("parent thread connfd: %d\n", connfd);
if (connfd == -1)
{
perror("accept");
exit(0);
}
pinfo->fd = connfd;
pthread_create(&pinfo->tid,NULL,working,pinfo);
}
return 0;
}
5、select IO 多路复用实现并发
//socket_sv3.c
//select IO mulputile concurrency
#include
#include
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char* argv){
//1.creat linsten socket
int lfd = socket(AF_INET, SOCK_STREAM,0);
if (lfd == -1)
{
perror("socket");
exit(0);
}
//2.bind lfd to local ip address and port
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(10000);
int ret = bind(lfd,(struct sockaddr *)&addr,sizeof(addr));
if (ret == -1){
perror("bind");
exit(0);
}
//3,listen
ret = listen(lfd, 128);
if (ret == -1)
{
perror("listen");
exit(0);
}
//transform lfd state chenck task to kernel
int maxfd = lfd;
//init rfd set
fd_set rdset;
fd_set rdtemp;
//zero
FD_ZERO(&rdset);
//set lfd to rdset
FD_SET(lfd, &rdset);
while (1)
{
rdtemp = rdset;
int num = select(maxfd+1, &rdtemp,NULL,NULL,NULL);
//check is data in read buf, when rdset index equal 1, and buf have data
if (FD_ISSET(lfd,&rdtemp)){
//have data in read buf, and accept will not block
struct sockaddr_in cliaddr;
int addrlen = sizeof(cliaddr);
int cfd = accept(lfd, (struct sockaddr *)&cliaddr,&addrlen);
if (cfd == -1)
{
perror("accept");
exit(0);
}
//print client information
char ip[24] = {0};
printf("client ip addres: %s, port: %d\n",
inet_ntop(AF_INET,&cliaddr.sin_addr.s_addr,ip,sizeof(ip)),ntohs(cliaddr.sin_port));
// add communicate fd to rdset , can dectect cfd in next cycle
FD_SET(cfd, &rdset);
//reset max fd
maxfd = cfd > maxfd? cfd: maxfd;
}
for (int i = 0; i < maxfd + 1; i++)
{
if (i != lfd && FD_ISSET(i, &rdtemp)){
//recv data
char buf[1024];
memset(buf,0 ,sizeof(buf));
int len = read(i, buf,sizeof(buf));
if (len > 0)
{
//send data
printf("recv from client: %s\n",buf);
write(i, buf, len);
}else if(len == 0){
printf("client disconnect...\n");
//delete dected fd from read fd set
FD_CLR(i, &rdset);
close(i);
}else{
perror("read");
}
}
}
}
close(lfd);
return 0;
}