开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网络基础和网络编程是IT领域中的重要组成部分,特别是在服务器端开发中不可或缺。本文将深入探讨这个主题,从Linux网络的基础知识开始,逐步讲解到Socket编程以及如何实现高并发服务器。 1. Linux网络基础: ...
Java网络编程中的TCP(Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。在Java中,我们通常使用Socket类来实现TCP网络编程。Socket是Java.IO包的一部分,提供了网络通信的...
本资料集专注于"Linux编程技术-多线程-网络编程",它涵盖了UNIX环境高级编程、Linux网络编程、Linux多线程编程、Linux窗口编程以及Linux脚本编程等多个核心主题。这些内容都是构建高效、可靠且可扩展的Linux应用的...
《Linux/UNIX系统编程手册》是一本旨在深入介绍Linux和UNIX系统编程接口的权威指南,该书由经验丰富的Linux编程专家Michael Kerrisk所著。 该手册详细描述了系统编程中必须掌握的系统调用和库函数。系统调用是用户...
《Linux-UNIX系统编程手册(上册)》是由Linux编程专家Michael Kerrisk撰写的一部权威指南,详细介绍了Linux和UNIX系统的编程接口。这本书是针对那些希望掌握系统编程技能的开发者,无论是在Linux还是其他UNIX平台上...
C/S模式和B/S模式是常见的网络应用程序设计模式: - C/S模式:客户端和服务器分别部署,客户端处理用户交互,服务器处理业务逻辑。优点是性能高,可定制性强,但客户端需安装,维护成本较高。 - B/S模式:基于...
QT_TCP.rar 文件包含了一个基于Linux平台的C/S(客户机/服务器)架构的TCP网络通信程序,使用了QT库来实现TCP套接字的交互。QT是一个跨平台的应用开发框架,特别适合于创建图形用户界面应用程序,同时也支持非GUI...
对于初学者,理解并实现这样一个文件传输系统可以帮助深入理解TCP/IP协议的工作原理,以及如何在Linux环境下进行网络编程。 总的来说,这个压缩包提供的资源可以帮助学习者掌握如何在Linux系统中利用TCP/IP协议实现...
GDB是GNU项目的一部分,是一款强大的源代码级调试器,支持多种编程语言,包括C、C++、Objective-C、Python等。在Android开发中,GDB用于远程调试应用程序,通过与设备上的目标程序进行通信,允许开发者查看变量值、...
在IT领域,Linux网络编程和TCP/IP协议是网络开发的核心部分。这些概念和技术构成了互联网通信的基础,对于系统管理员、软件开发者以及任何与网络打交道的人来说都至关重要。以下是对这些主题的详细解析: 首先,...
总的来说,Linux下的C语言编程涵盖了操作系统原理、系统调用、文件I/O、进程和线程管理、网络编程、内存管理等多个方面。通过不断实践和学习,开发者可以利用C语言的威力,充分挖掘Linux系统的潜力,创建高效、稳定...
此项目是基于Linux下的网络编程的一个扩展项目,基于网络的聊天工具,项目模块包括 Linux C 服务器, Linux C 客户端及数据库的制作。服务器采用 TCP 线并发服务器来实现多个客户端同时连接并占用服务器的情况,其中...
在Linux系统中,非堵塞(Non-blocking)TCP编程是一种高级网络编程技术,它允许程序以异步的方式处理网络I/O操作。非堵塞模式下,当一个socket无法立即完成读写操作时,系统调用不会阻塞,而是立刻返回,使得程序...
7. **并发服务器设计**:讨论单线程、多线程和多进程模型在构建网络服务器时的优缺点,以及如何选择和实现合适的并发模型。 8. **错误处理和调试**:学习如何处理网络编程中常见的错误,如连接中断、超时、内存不足...