开2个终端窗口:
1)
deepfuture@deepfuture-laptop:~/private/mytest$ ./testtcpc
client send....
client send :deepfuture.iteye.com
client read :hello
deepfuture@deepfuture-laptop:~/private/mytest$ ./testtcpc
client send....
client send :deepfuture.iteye.com
client read :hello
deepfuture@deepfuture-laptop:~/private/mytest$
2)
deepfuture@deepfuture-laptop:~/private/mytest$ ./testtcps
server wait....
server wait....
server read :deepfuture.iteye.com
server send :hello
server wait....
server read :deepfuture.iteye.com
server send :hello
二、客户端
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
//deepfuture.iteye.com
ssize_t readn(int fd,void *ptr,size_t maxcn){//读取n个字符,maxc为读取的数目
size_t noreadcn,readcn;
char *buf=ptr;
noreadcn=maxcn;
while(noreadcn>0){
if ( (readcn=read(fd,buf,noreadcn))<0){//读数据
if (errno==EINTR) {//数据读取前,操作被信号中断 deepfuture.iteye.com
perror("中断错误");
readcn=0;
}
else {return -1;}//无法修复错误,返回读取失败
}
else if(readcn==0) break;//EOF deepfuture.iteye.com
noreadcn-=readcn;//读取成功,但是如果读取的字符数小于maxc,则继续读,因为可能数据还会继续通过网络送过来
buf+=readcn;
if (*buf==0) break; //如果读到字符串结尾标志则退出,必须有这句,否则会死循环 deepfuture.iteye.com
}
return (maxcn-noreadcn);
}
ssize_t writen(int fd,void *ptr,size_t maxcn){//写入n个字符
size_t nowritecn,writecn;
char *buf=ptr;
nowritecn=maxcn;
while(nowritecn>0){
if((writecn=write(fd,buf,nowritecn))<=0){//写数据
if (errno==EINTR) {//数据写前,操作被信号中断
perror("中断错误");
writecn=0;
}
else {return -1;}//无法修复错误,返回读取失败
}
nowritecn-=writecn;
buf+=writecn;
}
return (maxcn-nowritecn);
}
int main(void){
int fd;
int addresslen;
struct sockaddr_in address;//地址信息结构 deepfuture.iteye.com
int pid;
char mybuf[100];
char *buf="deepfuture.iteye.com\n";
int rc;
fd=socket(AF_INET,SOCK_STREAM,0);//建立socket
if (fd==-1){//错误,类型从errno获得
perror("error");//perror先输出参数,后跟":"加空格,然后是errno值对应的错误信息(不是错误代码),最后是一个换行符。 deepfuture.iteye.com
}
printf("client send....\n");
fflush(stdout);
//连接
address.sin_family=AF_INET;//IPV4协议,AF_INET6是IPV6 deepfuture.iteye.com
address.sin_addr.s_addr=inet_addr("127.0.0.1");//l表示32位,htonl能保证在不同CPU的相同字节序
address.sin_port=htons(1253);//端口号,s表示16位 deepfuture.iteye.com
addresslen=sizeof(address);
rc=connect(fd,(struct sockaddr *)&address,addresslen);//连接服务器 deepfuture.iteye.com
if (rc==-1){//rc=0成功,rc=-1失败 deepfuture.iteye.com
perror("连接错误");
exit(1);
}
//发送数据
writen(fd,(void *)buf,strlen(buf)+1);
printf("client send :%s\n",buf);
//读取数据
bzero(mybuf,100);
readn(fd,(void *)mybuf,100);
printf("client read :%s\n",mybuf);
close(fd);
exit(0);
}
服务端
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
//deepfuture.iteye.com
ssize_t readn(int fd,void *ptr,size_t maxcn){//读取n个字符,maxc为读取的数目
size_t noreadcn,readcn;
char *buf=ptr;
noreadcn=maxcn;
while(noreadcn>0){
if ( (readcn=read(fd,buf,noreadcn))<0){//读数据
if (errno==EINTR) {//数据读取前,操作被信号中断
perror("中断错误");
readcn=0;
}
else {return -1;}//无法修复错误,返回读取失败
}
else if(readcn==0) break;//EOF
noreadcn-=readcn;//读取成功,但是如果读取的字符数小于maxc,则继续读,因为可能数据还会继续通过网络送过来
buf+=readcn;
if (*buf==0) break;//如果读到字符串结尾标志则退出,必须有这句,否则会死循环
}
return (maxcn-noreadcn);
}
ssize_t writen(int fd,void *ptr,size_t maxcn){//写入n个字符
size_t nowritecn,writecn;
char *buf=ptr;
nowritecn=maxcn;
while(nowritecn>0){
if((writecn=write(fd,buf,nowritecn))<=0){//写数据
if (errno==EINTR) {//数据写前,操作被信号中断
perror("中断错误");
writecn=0;
}
else {return -1;}//无法修复错误,返回读取失败
}
nowritecn-=writecn;
buf+=writecn;
}
return (maxcn-nowritecn);
}
int main(void){
int fd;
int addresslen;
struct sockaddr_in address;//地址信息结构
int pid;
int rc;
//建立socket
fd=socket(AF_INET,SOCK_STREAM,0);//fd为socket
if (fd==-1){//错误,类型从errno获得
perror("error");//perror先输出参数,后跟":"加空格,然后是errno值对应的错误信息(不是错误代码),最后是一个换行符。
}
//bind 到socket fd
address.sin_family=AF_INET;//IPV4协议,AF_INET6是IPV6
address.sin_addr.s_addr=htonl(INADDR_ANY);//l表示32位,htonl能保证在不同CPU的相同字节序
address.sin_port=htons(1253);//端口号,s表示16位
addresslen=sizeof(address);
bind(fd,(struct sockaddr *)&address,addresslen);//bind
//建立socket队列,指定最大可接受连接数
rc=listen(fd,32);//最多接收32个连接,开始监听
//int listen(int sockfd, int backlog)返回:0──成功, -1──失败
//内核会在自己的进程空间里维护一个队列以跟踪这些完成的连接但服务器进程还没有接手处理或正在进行的连接
if (rc==-1) {
perror("listen error");//监听失败
exit(1);
}
while(1){
struct sockaddr_in clientaddress;
int address_len;
int client_sockfd;
char mybuf[100];
char *buf="hello\n";
//等待连接,使用新的进程或线程来处理连接
printf("server wait....\n");
fflush(stdout);
address_len=sizeof(clientaddress);
client_sockfd=accept(fd,(struct sockaddr *)&clientaddress,&address_len);//client_sockfd可理解为一个文件句柄,能用read和write操作。client_address是客户端信息结构 deepfuture.iteye.com
//fork进程来处理每个客户的连接
pid=fork();
if (pid<0){//错误
printf("error:%s\n",strerror(errno));//strerror将errno映射为一个错误信息串 deepfuture.iteye.com
close(client_sockfd);
exit(1);
}
if (pid==0){ //子进程处理每个客户端的数据
close(fd);//子进程关闭不需要它处理的监听资源
//读取数据 deepfuture.iteye.com
bzero(mybuf,100);
readn(client_sockfd,(void *)mybuf,100);
printf("\nserver read :%s",mybuf);
//发送数据
writen(client_sockfd,(void *)buf,strlen(buf)+1);
printf("\nserver send :%s",buf);
close(client_sockfd);
exit(0);
}
else {//父进程
close(client_sockfd);//父进程不处理客户端连接,因此关闭,但并不意味着把子进程的处理句柄关闭,因为子进程继承了父进程的client_sockfd资源 deepfuture.iteye.com
}
}
}
分享到:
相关推荐
5、Linux网络编程05——C/S与B/S架构的区别 6、Linux网络编程06——UDP协议编程 7、Linux网络编程07——广播 8、Linux网络编程08——多播 9、Linux网络编程09——TCP编程之客户端 10、Linux网络编程10——TCP编程之...
此项目是基于Linux下的网络编程的一个扩展项目,基于网络的聊天工具,项目模块包括 Linux C 服务器, Linux C 客户端及数据库的制作。服务器采用 TCP 线并发服务器来实现多个客户端同时连接并占用服务器的情况,其中...
Linux网络编程之TCP/IP基础篇 Linux网络编程之socket编程篇 Linux网络编程之进程间通信篇 Linux网络编程之线程篇 Linux网络编程之TCP/IP基础篇 01TCPIP基础(一) ISO/OSI参考模型 TCP/IP四层模型 基本概念...
Linux网络编程之TCP/IP基础篇 Linux网络编程之socket编程篇 Linux网络编程之进程间通信篇 Linux网络编程之线程篇 Linux网络编程之TCP/IP基础篇 01TCPIP基础(一) ISO/OSI参考模型 TCP/IP四层模型 基本概念...
Linux下的基于TCP的网络编程实例,使用了多进程模式。代码较小,能快速掌握。
Linux网络编程里的多进程服务器和多线程服务器用到的错误封装函数, 对TCP下的C/S模型常用的函数进行返回值检查, 在主代码里可以省去返回值检查, 突出代码逻辑
服务器具有同时处理多个客户机的能力。 客户机:首先与相应服务器连接,然后接收用户输入的字符串,再将字符串发送到服务器,接收服务器发回的信息并显示。之后,继续等待用户输入直至用户输入Ctrl+D。当收到用户...
第2章 Linux编程环境 14 2.1 Linux环境下的编辑器 14 2.1.1 vim使用简介 14 2.1.2 使用vim建立文件 15 2.1.3 使用vim编辑文本 16 2.1.4 vim的格式设置 18 2.1.5 vim配置文件.vimrc 19 2.1.6 使用其他...
第2章 Linux编程环境 14 2.1 Linux环境下的编辑器 14 2.1.1 vim使用简介 14 2.1.2 使用vim建立文件 15 2.1.3 使用vim编辑文本 16 2.1.4 vim的格式设置 18 2.1.5 vim配置文件.vimrc 19 2.1.6 使用其他...
Linux网络编程指的是在Linux操作系统下进行网络编程的过程。Linux是一个开放源代码的操作系统,因此,它提供了丰富的网络编程接口和库函数,可以方便地实现网络通信。 Linux网络编程主要涉及以下内容: Socket编程...
Linux网络编程之TCP/IP基础篇 Linux网络编程之socket编程篇 Linux网络编程之进程间通信篇 Linux网络编程之线程篇 Linux网络编程之TCP/IP基础篇 01TCPIP基础(一) ISO/OSI参考模型 TCP/IP四层模型 基本概念...
《Linux多线程服务端编程:使用muduo C++网络库》主要讲述采用现代C++在x86-64 Linux上编写多线程TCP网络服务程序的主流常规技术,重点讲解一种适应性较强的多线程服务器的编程模型,即one loop per thread。...
Linux网络编程之TCP/IP基础篇 Linux网络编程之socket编程篇 Linux网络编程之进程间通信篇 Linux网络编程之线程篇 Linux网络编程之TCP/IP基础篇 01TCPIP基础(一) ISO/OSI参考模型 TCP/IP四层模型 基本概念...
本书主要讲述采用现代C++ 在x86-64 Linux 上编写多线程TCP 网络服务程序的主流常规技术,重点讲解一种适应性较强的多线程服务器的编程模型,即one loop per thread。这是在Linux 下以native 语言编写用户态高性能...
第二部分对高性能服务器编程的核心要素进行了全面深入的剖析,包含Linux网络编程API、高级I/O函数、Linux服务器程序规范、高性能服务器程序框架、I/O复用、信号、定时器、高性能I/O框架库Libevent、多进程编程、多...
11-多进程并发服务器思路分析.avi 12-多线程并发服务器分析.avi 13-多进程并发服务器实现avi 13-多进程服务器测试ip地址调整avi 14-服务器程序上传外网服务器,并访问.aviAV 15-多线程服务器代码review.avi AV 16-...
第2章 Linux编程环境 14 2.1 Linux环境下的编辑器 14 2.1.1 vim使用简介 14 2.1.2 使用vim建立文件 15 2.1.3 使用vim编辑文本 16 2.1.4 vim的格式设置 18 2.1.5 vim配置文件.vimrc 19 2.1.6 使用其他...
(1)在Linux系统下,使用TCP协议套接字编程; (2)服务器应具有处理多个客户端连接并计算的能力; (3)过程描述 客户端:连接服务器后,从键盘输入一连串的整数及字符串,并将这些整数及字符串发送到服务器,并...
第二部分对高性能服务器编程的核心要素进行了全面深入的剖析,包含Linux网络编程API、高级I/O函数、Linux服务器程序规范、高性能服务器程序框架、I/O复用、信号、定时器、高性能I/O框架库Libevent、多进程编程、多...
Linux网络编程之TCP/IP基础篇 Linux网络编程之socket编程篇 Linux网络编程之进程间通信篇 Linux网络编程之线程篇 Linux网络编程之TCP/IP基础篇 01TCPIP基础(一) ISO/OSI参考模型 TCP/IP四层模型 基本概念...