该网络编程之客户端与服务端程序模板支持:

1. 多客户端同时连接服务端,即服务程序可以同时为多个客户端服务;

2. 服务端支持套接字对重用,即即使处于TIME_WAIT状态,仍可支持服务端重启;

3. 服务端可以发现客户端是否已断开连接;

4. 支持客户端标准输入会显,服务端从标准输出显示客户端所输入内容。

程序如下,记下该模板以备再次使用:

客户端程序如下:

/*************************************************************************
> File Name: p2pcli.c
> Author: ma6174
> Mail: ma6174@163.com
> Created Time: Sun 05 Oct 2014 09:26:40 PM HKT
************************************************************************/ #include<stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h> #include <sys/types.h>
#include <netinet/in.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h> #define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
}while() int main(int argc, char **argv)
{
int sockfd;
struct sockaddr_in servaddr; if(argc != )
{
//printf("usage: p2pcli <IPaddress> ");
//exit(0);
ERR_EXIT("usage: p2pcli <IPaddress> ");
} sockfd = socket(AF_INET, SOCK_STREAM, ); memset(&servaddr, , sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons();
servaddr.sin_addr.s_addr = inet_addr(argv[]); if(connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < )
{
ERR_EXIT("connect");
} //communication
char sendbuf[] = {};
char recvbuf[] = {};
while(fgets(sendbuf, sizeof(sendbuf), stdin) != NULL)
{
//send to server.
write(sockfd, sendbuf, strlen(sendbuf));
//read from server to display.
read(sockfd, recvbuf, sizeof(recvbuf)); //display
fputs(recvbuf, stdout);
memset(sendbuf, , sizeof(sendbuf));
memset(recvbuf, , sizeof(recvbuf));
}
close(sockfd);
return ;
}

服务端程序如下:

/*************************************************************************
> File Name: p2psrv.c
> Author: ma6174
> Mail: ma6174@163.com
> Created Time: Sun 05 Oct 2014 08:27:06 PM HKT
************************************************************************/ #include<stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h> #include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h> #define ERR_EXIT(m)\
do\
{\
perror(m);\
exit(EXIT_FAILURE);\
}while() void do_service(int connfd)
{
//communication
char recvbuf[];
while()
{
memset(recvbuf, , sizeof(recvbuf));
int ret = read(connfd, recvbuf, sizeof(recvbuf));
if(ret == )
{
printf("client close.\n");
break;
}
else if(ret == -)
{
break;
}
else
{
fputs(recvbuf, stdout);
write(connfd, recvbuf, ret);
}
}
} int main()
{
int listenfd;
if( (listenfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < )
{
ERR_EXIT("socket");
} struct sockaddr_in servaddr;
memset(&servaddr, , sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons();
servaddr.sin_addr.s_addr = htonl(INADDR_ANY); //reuse address
int on = ;
if(setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)))
{
ERR_EXIT("setsockopt");
} if(bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < )
{
ERR_EXIT("bind");
} if(listen(listenfd, SOMAXCONN) < )
{
ERR_EXIT("listen");
} struct sockaddr_in peeraddr;
socklen_t peerlen = sizeof(peeraddr);
int connfd; //muti client
pid_t pid;
while()
{
if( (connfd = accept(listenfd, (struct sockaddr*)&peeraddr, &peerlen)) < )
{
ERR_EXIT("accept");
} printf("ip=%s, port=%d\n", inet_ntoa(peeraddr.sin_addr), ntohs(peeraddr.sin_port)); pid = fork();
if(pid == -)
{
ERR_EXIT("fork");
}
else if(pid == )
{
//child
close(listenfd);
do_service(connfd);
exit();
}
else
{
close(connfd); }
}
close(connfd);
close(listenfd);
return ;
}

《UNIX网络编程》之多客户连接服务端,可重用套接字对的更多相关文章

  1. 《Unix网络编程》卷一(简介TCP/IP、基础套接字编程)

    通常说函数返回某个错误值,实际上是函数返回值为-1,而全局变量errno被置为指定的常值(即称函数返回这个错误值). exit终止进程,Unix在一个进程终止时总是关闭该进程所有打开的描述符. TCP ...

  2. TCP/IP网络编程之基于TCP的服务端/客户端(二)

    回声客户端问题 上一章TCP/IP网络编程之基于TCP的服务端/客户端(一)中,我们解释了回声客户端所存在的问题,那么单单是客户端的问题,服务端没有任何问题?是的,服务端没有问题,现在先让我们回顾下服 ...

  3. TCP/IP网络编程之基于UDP的服务端/客户端

    理解UDP 在之前学习TCP的过程中,我们还了解了TCP/IP协议栈.在四层TCP/IP模型中,传输层分为TCP和UDP这两种.数据交换过程可以分为通过TCP套接字完成的TCP方式和通过UDP套接字完 ...

  4. TCP/IP网络编程之基于TCP的服务端/客户端(一)

    理解TCP和UDP 根据数据传输方式的不同,基于网络协议的套接字一般分为TCP套接字和UDP套接字.因为TCP套接字是面向连接的,因此又称为基于流(stream)的套接字.TCP是Transmissi ...

  5. 【Unix 网络编程】TCP 客户/服务器简单 Socket 程序

    建立一个 TCP 连接时会发生下述情形: 1. 服务器必须准备好接受外来的连接.这通常通过调用 socket.bind 和 listen 这三个函数来完成,我们称之为被动打开. 2. 客户通过调用 c ...

  6. java网络编程TCP传输—流操作—服务端反馈与客户端接收

    在读取完流后,服务端会向客户端返回一些数据,告诉客户端,已经写完了. 在这里和”流操作—拿到源后的写入动作“差不多,客户端同样以byte与Buffered两种缓冲读取作为例子,同时,.也是希望大家给补 ...

  7. (网络编程)基于tcp(粘包问题) udp协议的套接字通信

    import   socket 1.通信套接字(1人1句)服务端和1个客户端 2.通信循环(1人多句)服务端和1个客户端 3.通信循环(多人(串行)多句)多个客户端(服务端服务死:1个客户端---&g ...

  8. python 网络编程(四)---UDP服务端客户端

    1.服务器端 UDP服务器建立与TCP相类似,具体比较如下: 补充下,第四步:不必使用listen还有accept函数. 具体代码如下:(设置socket选项省略) import socket fro ...

  9. [javaSE] 网络编程(浏览器客户端-自定义服务端)

    获取ServerSocket对象,new出来构造参数:int类型端口号 调用ServerSocket对象的accept()方法,得到Socket对象 获取PrintWriter对象,new出来,构造参 ...

随机推荐

  1. MySQL 连接

    MySQL 连接 使用mysql二进制方式连接 您可以使用MySQL二进制方式进入到mysql命令提示符下来连接MySQL数据库. 实例 以下是从命令行中连接mysql服务器的简单实例: [root@ ...

  2. Eclipse代码注释模板修改

    /** * @ClassName: ${type_name} * @author: <font color="red"><b>ZF</b>< ...

  3. springmvc数组参数传递

    在开发中遇到将form中的name值一样的多个input元素传递到后台,我用的是springmvc. 刚开始的时候老是报400的请求错误.后来查了下资料,其实解决方案挺简单的. 我的后台control ...

  4. php设计模式之单例模式

    单例模式顾名思义,就是只有一个实例.作为对象的创建模式, 单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例. 单例模式的要点有三个: 一是某个类只能有一个实例: 二是它必须自行 ...

  5. HTML 表格、区块、其他常用控件

    1. HTML 表格 主要关键字: table:表格: table border 属性:定义边框 -- <table border="1">: caption:表名: ...

  6. 伯克利DB的一个BUG

    一旦没有手工close掉伯克利DB,则缓存里的数据不会主动写入到文件中,因此非常难于排查这个BUG,记录在这里提醒自己

  7. 基于MINA框架快速开发网络应用程序

    1.MINA框架简介 MINA(Multipurpose Infrastructure for Network Applications)是用于开发高性能和高可用性的网络应用程序的基础框架.通过使用M ...

  8. 理解ThreadLocal(转)

    小结 ThreadLocal是解决线程安全问题一个很好的思路,它通过为每个线程提供一个独立的变量副本解决了变量并发访问的冲突问题.在很多情况下,ThreadLocal比直接使用synchronized ...

  9. 【HDOJ】1348 Wall

    计算几何-凸包模板题目,Graham算法解. /* 1348 */ #include <iostream> #include <cstdio> #include <cst ...

  10. 【HDOJ】4982 Goffi and Squary Partition

    题意就是整数划分,选出和为n的K个整数,其中K-1个数的和为完全平方数S.选择整数时需要从1,2,3..连续选择,当选择整数与n-S相等时,需要跳过n-S,即选择n-S+1.如此选择K-2个数,从而可 ...