天天看点

linux之C编程实战小例

人生匆匆一趟,打不打酱油?怎么打?怎么打"质量好点的酱油"?由你决定.打酱油是一种态度,更是一种生活!

请记住下面些许话:

不要一味的说别人激进,只是你没别人有思想,比别人落伍而已,要是你有此思想的,请闭门思过哦,哈哈,温情的调侃下;

凡是好好说,说好,说清楚;

简单只能是自己告诉自己的,别人要是告诉你简单,那就是一种赤裸裸的忽悠!

做技术的有货再吼嗓门,没的请沉默,千万,别瞎说,不然则误人羞自,说出去的话嘛...;

在技术道路上,做一个有思想的人,期待与每一位热爱思考的人交流,您的关注是对我最大的支持;

Once first remember ruiy brother,thus so,永远是好兄弟,凡是见好就收,适可而止,没有永远的敌人,只有征途上的好兄弟;

备注,是征途一起的兄弟你我都知道,搞技术的并不是Copy-paste那么简单,所以请漠视Copy->paste,要善于用心总结,自己体会吧,话虽不太好听,但大多是真话,真假请自行辨别;

ruiy哥喜欢八卦,更喜欢没事聊聊天,扯扯话茬,但得找对人,找到知己,所谓的话不投机半句多,酒逢知己醉则休,不扯了,来日方长,此篇幅有限;

1,C之多线程实战;

tcpServerSocketPthread部分源码如图:

tcpClientSocketPthread部分源码预览如图:

完整源码下载链接>>>

<a href="http://files.cnblogs.com/ruiy/Pths.zip">http://files.cnblogs.com/ruiy/Pths.zip</a>

  {备注,可执行程序实用环境为POSIX(linux)系统,C的跨平台性不体现在java话语即一次编译到处运行,那是JVM干的,C的可执行程序要是想在windows等非宿主机下玩转,请自行在目标平台从新编译附件中的源码,用于链接不同平台下的lib,谢谢;}

2,C 操作mysql库,实现简单"增删改查"实战;

部分源码预览:

源码下载:

3,C网间主机文件传输实战;

4,socket编程之tcp实战;

源码下载:http://files.cnblogs.com/ruiy/ha.zip

5,socket编程之udp实战;

 源码:http://files.cnblogs.com/ruiy/ha.zip

附,辅助开发;

a.  在Windows下映射linux磁盘驱动器samba;

emacs /etc/samba/smb.conf

[NetLogin]

#comment = NetWork login serveice

path = /home

guest ok = yes

read only = no

writeable = yes

browseable = yes

同样在linux可以挂载windows下的共享磁盘驱动器;

b.  C socket bug;

http://blog.chinaunix.net/uid-233938-id-162618.html

c.  网络编程之socket概念解读;

生活于网络时代,网络通信与你我信息相关,此时ruiy与您一起解读网络通信实现之网络中进程间通信相关eg:网游客户端VS服务端,QQ客户端PK服务器,浏览器VS web服务器so.

上面的网络通信靠的绝大部分是socket;

  1,socket基本操作;

    socket(),bind(),listen(),connect(),accept(),read(),write(),close();

  2,socket三次Handshake Bind Connect,四次断开连接;

 网络间进程间通信解读;

  1,本地IPC(Internet Process Connection)方式

    a,消息传递(pipe,FIFO,msg queue pairs);

    b,同步;

    c,共享内存;

    d,远程过程调用(solairs door及SUN RPC-remote produce call);

网络中进程间通信的首要解决的问题是,如何在网络中唯一标识一个进程?在本地PID则可以!哈哈:相信你应该想起了吧,TCP/IP啊;

  网络层的ip地址--&gt;可以唯一标识网络中的主机;

  传输层的协议+端口--&gt;可以标识主机中的应用程序(就是进程啊!);

    因此则ok了,ip+协议+端口,就能完成网络中唯一标识进程的任务啦!

应用程序通常采用的应用编程接口有:UNIX BSD套接字接口(socket)和UNIX system V的TLI(基本被抛弃);

网络间的通信通常用的都是socket,socket又源于unix,而unix/linux基本哲学之一就是"一切皆文件";

用打开open-&gt;读写read/write-&gt;close关闭模式来操作,socket就是该模式的应用;

  socket就是一种特殊的文件,socket函数就是对其进行打开读写关闭操作,socket的名词定义可溯源到1970左右!

1,  int socket(int domain,int type,int protocol)相当于普通文件的打开操作;

domain:表示协议簇family,常用的地址协议簇有:AF_INET,AF_INET6,AF_LOCAL(AF_UNIX,unix的域socket),AF_ROUTE;

type:表示socket类型,主要的socket类型,SOCK_STREAM,SOCK_DGRAM,SOCK_RAM,SOCK_PACKET,SOCK_SEQPACKET;

protocol:表示协议类似,主要有,IPPROTO_TCP,IPPROTO_UDP,IPPROTO_SCTP(stream control transmission protocl,下一代Tcp),IPPROTO_TIPC(主要用于HAL及动态集群环境);

并不是上面的type和protocol可以随意组合的,如SOCK_STREAM不可以跟IPPROTO_UDP组合。当protocol为0时,会自动选择type类型对应的默认协议;

2,  int bind(int sockfd,const struct sockaddr *addr,socklen_t addrlen);

socket,由上面的socket建立的socket文件描述字;

addr是个结构体指针变量指向要绑定给socket_fd的协议簇

struct sockaddr_in{

  sa(selective availability)_family_t sin_family;/*address family:AF_INET*/

  in_port_t sin_port; /*port in network byte order*/

  struct in_addr sin_addr;/*internet address*/

}

 int listen(int sockfd,int backlog);

参数sockfd为服务端要监听的socket描述字,backlog为可排队的连接数,实际请求数大于此数值时,服务端则拒绝后来的请求;

int connect(int sockfd,const struct sockaddr *addr,socklen_t addrlen);

此种的sockfd为客户端的socket描述字,const struct sockaddr *addr为服务端的socket地址,addrlen为地址长度;

TCP服务器端依次调用socket()、bind()、listen()之后,就会监听指定的socket地址了。TCP客户端依次调用socket()、connect()之后就想TCP服务器发送了一个连接请求。TCP服务器监听到这个请求之后,就会调用accept()函数取接收请求,这样连接就建立好了。之后就可以开始网络I/O操作了,即类同于普通文件的读写I/O操作。

int accept(int sockfd,struct sockaddr *addr&gt;&gt;返回客户端协议地址,socklen_t addrlen);

tcp的socket通信中会产生2个监听socket,一个是服务端的--&gt;称为监听socket,另一个是以连接的socket,一个服务器通常通常仅仅只创建一个监听socket描述字,它在该服务器的生命周期内一直存在。内核为每个由服务器进程接受的客户连接创建了一个已连接socket描述字,当服务器完成了对某个客户的服务,相应的已连接socket描述字就被关闭。

网络IO分为如下几组:

read()/write();

recv()/send();

readv()/writev();

recvmsg()/sendmsg();最通用的网络IO.

recvfrom()/sendto();

函数原型;

#include &lt;unistd.h&gt;

ssize_t read(int fd,void *buf,size_t count);

ssize_t write(int fd,const void *buf,size_t count);

#include &lt;sys/types.h&gt;

#include &lt;sys/socket.h&gt;

ssize_t send(int sockfd,const void *buf,size_t len,int flags);

sisze_t recv(int sockfd,void *buf,size_t len,int flags);

ssize_t sendto(int sockfd,void *buf,size_t len,int flags,const struct sockaddr *dest_addr,socklen_t *addrlen);

ssize_t recvfrom(int sockfd,void *buf,size_t len,int flags,struct sockadrr *src_addr,socklen_t *addrlen);

ssize_t sendmsg(int sockfd,const struct msghdr *msg,int falgs);

ssize_t recvmsg(int sockfd,struct msghdr *msg,int falgs);

具体在linux系统下,请man func_name;

 tcp,udp之socket编程异同;

打开sockfd是用的type不一样;

int socket(int domain,int type,int protocol);

tcp用SOCK_STREAM,udp用SOCK_DGRAM;

  tcp面向连接,主机间交互前必须通过三次握手建立连接信道;

  udp面向无连接,交互前不需建立连接,主要设定需要发往的目的主机即可,即填写需发往的ip及端口,此地址可以在互联网上不存在,那结果就是消息发不到目的地,结果也是对的啊,哈哈,udp就是这样的,它只管发,结果如何咱不管啊!!!

  TCP具有高可靠性,确保传输数据的正确性,不出现丢失或乱序;UDP在传输数据前不建立连接,不对数据报进行检查与修改,无须等待对方的应答,所以会出现分组丢失、重复、乱序,应用程序需要负责传输可靠性方面的所有工作;

  也正因为以上特征,UDP具有较好的实时性,工作效率较TCP协议高;

  UDP段结构比TCP的段结构简单,因此网络开销也小。

总结;二种协议没有好坏,只有适合,有时候二者结合,比如就是两种协议都有,比如组播通信的时候只能用udp

Over,到此为止吧,祝所有阅此篇文的哥们,好运,有一天那个哥们创业算ruiy哥一个,哥能搭把手搞搞技术DBA,POSIX系统运维,NOSQL简单架构等等,ruiy努力一把看看文档(最好是offical offer 文档,英文的也凑合能看懂些,毕竟有挑战,有门槛,才 有价值嘛!)ruiy哥我再奋战几日,就算搞不到啥啥那所谓的啥精通(我這是套话啊,你我都懂的,笑笑飘过吧,开个玩笑嘛,大家都放松一把),也能搞个七八成火候,哈哈,话又说回来了,人毕竟年龄大了,脑袋不好使了,记忆力下降了,诸事繁杂,不能全身心投入了,但请注意,请千万注意,哥还是有点底子的,数年从业经历哥可都是认认真真打酱油过来的,基础阅历还行.没办法穷的叮当响了,卖艺,弄口饭吃!

编译时偶遇报错信息如下

那就是在用fopen函数打开文件,加参数时,第二个参数模式字符时,我讲它不久一个r 或是w 或是 x嘛,所以就以为它是字符,所以我就给它来了个单引号,可以我错了,完全的错了,它还有别的模式是w+,rw+二进制什么的,所以不管它当前是几个字符组成的字符串都要用双引号;

,'r'千万不要这么干;

总的报错信息

记录下调试过程;

继续阅读