天天看點

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'千萬不要這麼幹;

總的報錯資訊

記錄下調試過程;

繼續閱讀