﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-I smell magic in the air-随笔分类-socket</title><link>http://www.cppblog.com/izualzhy/category/19725.html</link><description>坚持 相信自己</description><language>zh-cn</language><lastBuildDate>Thu, 09 Aug 2012 17:44:19 GMT</lastBuildDate><pubDate>Thu, 09 Aug 2012 17:44:19 GMT</pubDate><ttl>60</ttl><item><title>socket编写简单聊天程序</title><link>http://www.cppblog.com/izualzhy/archive/2012/08/04/186269.html</link><dc:creator>izualzhy</dc:creator><author>izualzhy</author><pubDate>Sat, 04 Aug 2012 09:15:00 GMT</pubDate><guid>http://www.cppblog.com/izualzhy/archive/2012/08/04/186269.html</guid><wfw:comment>http://www.cppblog.com/izualzhy/comments/186269.html</wfw:comment><comments>http://www.cppblog.com/izualzhy/archive/2012/08/04/186269.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/izualzhy/comments/commentRss/186269.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/izualzhy/services/trackbacks/186269.html</trackback:ping><description><![CDATA[<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:a8c5b14a-54d0-47f1-bea3-bf8e4ee3e555" class="wlWriterEditableSmartContent">Technorati 标签: <a href="http://technorati.com/tags/socket" rel="tag">socket</a></div> <p>算是socket的一个小练习，免得自己眼高手低。</p> <p>聊天一方充当server，而另一方充当client。</p> <p>在accept使用上卡了很久，一直提示Bad Address。结果发现最后一个参数有的是int,有的是int*，目前还不理解是为什么。</p> <p>直接贴下程序，目前只能等对方说一句话后才能说，不知道怎么才能改进一下呢？</p> <p>想到的就是想qq聊天窗口那样，输入与显示要分开才行。</p> <p>如果实在terminal，如果输入的时候对方的消息过来，应该怎么办？</p> <p>一方面要随时可以输入(scanf等待)，一方面要随时接收输出，应该时要使用多线程没错的。不过还是没想到怎么具体解决.</p> <p>贴下现有的代码</p> <p>充当客户端的一方：</p><pre class="code"><span style="color: #2e53d1"><pre class="code"><span style="color: #937a42">/*
 * =====================================================================================
 *       Filename:  TalkServer.c
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  08/04/2012 02:35:01 PM
 *
 *         Author:  zhy (), izualzhy@163.com
 * =====================================================================================
 */

</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;stdio.h&gt;
</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;error.h&gt;
</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;sys/socket.h&gt;
</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;netinet/in.h&gt;

</span><span style="color: #400080">#define </span>TALKPORT <span style="color: #259241">1234

</span><span style="color: #400080">int </span>main<span style="color: #2e53d1">()
{
    </span><span style="color: #400080">int </span>sockfd<span style="color: #2e53d1">, </span>clientSockfd<span style="color: #2e53d1">, </span>recvbytes<span style="color: #2e53d1">;
    </span><span style="color: #400080">struct </span>sockaddr_in myAddr<span style="color: #2e53d1">;
    </span><span style="color: #400080">struct </span>sockaddr_in clientAddr<span style="color: #2e53d1">;

    </span><span style="color: #400080">if </span><span style="color: #2e53d1">((</span>sockfd <span style="color: #2e53d1">= </span>socket<span style="color: #2e53d1">(</span>AF_INET<span style="color: #2e53d1">, </span>SOCK_STREAM<span style="color: #2e53d1">, </span><span style="color: #259241">0</span><span style="color: #2e53d1">)) == -</span><span style="color: #259241">1</span><span style="color: #2e53d1">)
    {
        </span>perror<span style="color: #2e53d1">(</span><span style="color: #259241">"socket create error\n"</span><span style="color: #2e53d1">);
        </span>exit<span style="color: #2e53d1">(</span><span style="color: #259241">1</span><span style="color: #2e53d1">);
    }
    
    </span>myAddr<span style="color: #2e53d1">.</span>sin_family <span style="color: #2e53d1">= </span>AF_INET<span style="color: #2e53d1">;
    </span>myAddr<span style="color: #2e53d1">.</span>sin_port <span style="color: #2e53d1">= </span>htons<span style="color: #2e53d1">(</span>TALKPORT<span style="color: #2e53d1">);
    </span>myAddr<span style="color: #2e53d1">.</span>sin_addr<span style="color: #2e53d1">.</span>s_addr <span style="color: #2e53d1">= </span>INADDR_ANY<span style="color: #2e53d1">;
    </span>bzero<span style="color: #2e53d1">(&amp;</span>myAddr<span style="color: #2e53d1">.</span>sin_zero<span style="color: #2e53d1">, </span><span style="color: #259241">8</span><span style="color: #2e53d1">);

    </span><span style="color: #400080">if </span><span style="color: #2e53d1">(</span>bind<span style="color: #2e53d1">(</span>sockfd<span style="color: #2e53d1">, (</span><span style="color: #400080">struct </span>sockaddr<span style="color: #2e53d1">*)&amp;</span>myAddr<span style="color: #2e53d1">, </span><span style="color: #400080">sizeof</span><span style="color: #2e53d1">(</span><span style="color: #400080">struct </span>sockaddr<span style="color: #2e53d1">)) == -</span><span style="color: #259241">1</span><span style="color: #2e53d1">)
    {
        </span>perror<span style="color: #2e53d1">(</span><span style="color: #259241">"socket bind error\n"</span><span style="color: #2e53d1">);
        </span>exit<span style="color: #2e53d1">(</span><span style="color: #259241">1</span><span style="color: #2e53d1">);
    }

    </span><span style="color: #400080">if </span><span style="color: #2e53d1">(</span>listen<span style="color: #2e53d1">(</span>sockfd<span style="color: #2e53d1">, </span><span style="color: #259241">10</span><span style="color: #2e53d1">) == -</span><span style="color: #259241">1</span><span style="color: #2e53d1">)
    {
        </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"socket listen error\n"</span><span style="color: #2e53d1">);
        </span>exit<span style="color: #2e53d1">(</span><span style="color: #259241">1</span><span style="color: #2e53d1">);
    }

    </span><span style="color: #400080">while </span><span style="color: #2e53d1">(</span><span style="color: #259241">1</span><span style="color: #2e53d1">)
    {
        </span><span style="color: #400080">unsigned int </span>sin_size <span style="color: #2e53d1">= </span><span style="color: #400080">sizeof</span><span style="color: #2e53d1">(</span><span style="color: #400080">struct </span>sockaddr_in<span style="color: #2e53d1">);
        </span><span style="color: #400080">if </span><span style="color: #2e53d1">((</span>clientSockfd <span style="color: #2e53d1">= </span>accept<span style="color: #2e53d1">(</span>sockfd<span style="color: #2e53d1">, (</span><span style="color: #400080">struct </span>sockaddr<span style="color: #2e53d1">*)&amp;</span>clientAddr<span style="color: #2e53d1">, &amp;</span>sin_size<span style="color: #2e53d1">)) == -</span><span style="color: #259241">1</span><span style="color: #2e53d1">)
        {
            </span>perror<span style="color: #2e53d1">(</span><span style="color: #259241">"socket accept error"</span><span style="color: #2e53d1">);
            </span>exit<span style="color: #2e53d1">(</span><span style="color: #259241">1</span><span style="color: #2e53d1">);
        }
        </span><span style="color: #400080">else
        </span><span style="color: #2e53d1">{
            </span>send<span style="color: #2e53d1">(</span>clientSockfd<span style="color: #2e53d1">, </span><span style="color: #259241">"u got me!"</span><span style="color: #2e53d1">, </span><span style="color: #259241">10</span><span style="color: #2e53d1">, </span><span style="color: #259241">0</span><span style="color: #2e53d1">);
            </span><span style="color: #400080">break</span><span style="color: #2e53d1">;
        }

    }

    </span><span style="color: #400080">while </span><span style="color: #2e53d1">(</span><span style="color: #259241">1</span><span style="color: #2e53d1">)
    {
        </span><span style="color: #400080">char </span>recvmsg<span style="color: #2e53d1">[</span><span style="color: #259241">256</span><span style="color: #2e53d1">] = {</span><span style="color: #259241">0</span><span style="color: #2e53d1">};
        </span><span style="color: #400080">if </span><span style="color: #2e53d1">((</span>recvbytes <span style="color: #2e53d1">= </span>recv<span style="color: #2e53d1">(</span>clientSockfd<span style="color: #2e53d1">, </span>recvmsg<span style="color: #2e53d1">, </span><span style="color: #259241">256</span><span style="color: #2e53d1">, </span><span style="color: #259241">0</span><span style="color: #2e53d1">)) == -</span><span style="color: #259241">1</span><span style="color: #2e53d1">)
        {
            </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"recv msg: %s error\n"</span><span style="color: #2e53d1">, </span>recvmsg<span style="color: #2e53d1">);
            </span>exit<span style="color: #2e53d1">(</span><span style="color: #259241">1</span><span style="color: #2e53d1">);
        }
        </span><span style="color: #400080">else
        </span><span style="color: #2e53d1">{
            </span>recvmsg<span style="color: #2e53d1">[</span>recvbytes<span style="color: #2e53d1">] = </span><span style="color: #259241">'\0'</span><span style="color: #2e53d1">;
            </span><span style="color: #400080">if </span><span style="color: #2e53d1">(</span>strcmp<span style="color: #2e53d1">(</span>recvmsg<span style="color: #2e53d1">, </span><span style="color: #259241">"greedisgood"</span><span style="color: #2e53d1">) == </span><span style="color: #259241">0</span><span style="color: #2e53d1">)
            {
                </span>send<span style="color: #2e53d1">(</span>clientSockfd<span style="color: #2e53d1">, </span><span style="color: #259241">"greedisgood"</span><span style="color: #2e53d1">, </span><span style="color: #259241">12</span><span style="color: #2e53d1">, </span><span style="color: #259241">0</span><span style="color: #2e53d1">);
                </span><span style="color: #400080">break</span><span style="color: #2e53d1">;
            }
            </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"says: %s\n"</span><span style="color: #2e53d1">, </span>recvmsg<span style="color: #2e53d1">);
            </span><span style="color: #400080">char </span>sendmsg<span style="color: #2e53d1">[</span><span style="color: #259241">256</span><span style="color: #2e53d1">] = {</span><span style="color: #259241">0</span><span style="color: #2e53d1">};
            </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"&gt;: "</span><span style="color: #2e53d1">);
            </span>gets<span style="color: #2e53d1">(</span>sendmsg<span style="color: #2e53d1">);
            </span><span style="color: #400080">if </span><span style="color: #2e53d1">(</span>send<span style="color: #2e53d1">(</span>clientSockfd<span style="color: #2e53d1">, </span>sendmsg<span style="color: #2e53d1">, </span><span style="color: #400080">sizeof</span><span style="color: #2e53d1">(</span>sendmsg<span style="color: #2e53d1">), </span><span style="color: #259241">0</span><span style="color: #2e53d1">) == -</span><span style="color: #259241">1</span><span style="color: #2e53d1">)
            {
                </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"send msg: %s error\n"</span><span style="color: #2e53d1">, </span>sendmsg<span style="color: #2e53d1">);
                </span>exit<span style="color: #2e53d1">(</span><span style="color: #259241">1</span><span style="color: #2e53d1">);
            }
        }

    }

    </span>close<span style="color: #2e53d1">(</span>clientSockfd<span style="color: #2e53d1">);
    </span>close<span style="color: #2e53d1">(</span>sockfd<span style="color: #2e53d1">);

    </span><span style="color: #400080">return </span><span style="color: #259241">0</span><span style="color: #2e53d1">;
}

</span></pre>
<font color="#000000" face="微软雅黑">充当客户端的一方：</font></span></pre><pre class="code"><span style="color: #937a42"><pre class="code"><span style="color: #937a42">/*
 * =====================================================================================
 *       Filename:  TalkClient.c
 *    Description:  talker as client
 *
 *        Version:  1.0
 *        Created:  08/04/2012 03:05:52 PM
 *
 *         Author:  zhy (), izualzhy@163.com
 * =====================================================================================
 */

</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;string.h&gt;
</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;stdio.h&gt;
</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;sys/socket.h&gt;
</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;netinet/in.h&gt;
</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;netdb.h&gt;

</span><span style="color: #400080">#define </span>TALKPORT <span style="color: #259241">1234

</span><span style="color: #400080">int </span>main<span style="color: #2e53d1">(</span><span style="color: #400080">int </span>argc<span style="color: #2e53d1">, </span><span style="color: #400080">char</span><span style="color: #2e53d1">* </span>argv<span style="color: #2e53d1">[])
{
    </span><span style="color: #400080">int </span>serverSockfd<span style="color: #2e53d1">, </span>recvbytes<span style="color: #2e53d1">;
    </span><span style="color: #400080">struct </span>sockaddr_in serverSockAddr<span style="color: #2e53d1">;
    </span><span style="color: #400080">struct </span>hostent<span style="color: #2e53d1">* </span>host<span style="color: #2e53d1">;

    </span><span style="color: #400080">if </span><span style="color: #2e53d1">((</span>serverSockfd <span style="color: #2e53d1">= </span>socket<span style="color: #2e53d1">(</span>AF_INET<span style="color: #2e53d1">, </span>SOCK_STREAM<span style="color: #2e53d1">, </span><span style="color: #259241">0</span><span style="color: #2e53d1">)) == -</span><span style="color: #259241">1</span><span style="color: #2e53d1">)
    {
        </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"socket create error\n"</span><span style="color: #2e53d1">);
        </span>exit<span style="color: #2e53d1">(</span><span style="color: #259241">1</span><span style="color: #2e53d1">);
    }

    </span><span style="color: #400080">if </span><span style="color: #2e53d1">((</span>host <span style="color: #2e53d1">= </span>gethostbyname<span style="color: #2e53d1">(</span>argv<span style="color: #2e53d1">[</span><span style="color: #259241">1</span><span style="color: #2e53d1">])) == </span>NULL<span style="color: #2e53d1">)
    {
        </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"gethostbyname error\n"</span><span style="color: #2e53d1">);
        </span>exit<span style="color: #2e53d1">(</span><span style="color: #259241">1</span><span style="color: #2e53d1">);
    }

    </span>serverSockAddr<span style="color: #2e53d1">.</span>sin_family <span style="color: #2e53d1">= </span>AF_INET<span style="color: #2e53d1">;
    </span>serverSockAddr<span style="color: #2e53d1">.</span>sin_port <span style="color: #2e53d1">= </span>htons<span style="color: #2e53d1">(</span>TALKPORT<span style="color: #2e53d1">);
    </span>serverSockAddr<span style="color: #2e53d1">.</span>sin_addr <span style="color: #2e53d1">= *((</span><span style="color: #400080">struct </span>in_addr<span style="color: #2e53d1">*)</span>host<span style="color: #2e53d1">-&gt;</span>h_addr<span style="color: #2e53d1">);
    </span>bzero<span style="color: #2e53d1">(&amp;</span>serverSockAddr<span style="color: #2e53d1">.</span>sin_zero<span style="color: #2e53d1">, </span><span style="color: #259241">8</span><span style="color: #2e53d1">);
    </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"server: %s\n"</span><span style="color: #2e53d1">, </span>inet_ntoa<span style="color: #2e53d1">(</span>serverSockAddr<span style="color: #2e53d1">.</span>sin_addr<span style="color: #2e53d1">));

    </span><span style="color: #400080">if </span><span style="color: #2e53d1">(</span>connect<span style="color: #2e53d1">(</span>serverSockfd<span style="color: #2e53d1">, (</span><span style="color: #400080">struct </span>sockaddr<span style="color: #2e53d1">*)(&amp;</span>serverSockAddr<span style="color: #2e53d1">), </span><span style="color: #400080">sizeof</span><span style="color: #2e53d1">(</span><span style="color: #400080">struct </span>sockaddr<span style="color: #2e53d1">)) == -</span><span style="color: #259241">1</span><span style="color: #2e53d1">)
    {
        </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"socket connect error\n"</span><span style="color: #2e53d1">);
        </span>exit<span style="color: #2e53d1">(</span><span style="color: #259241">1</span><span style="color: #2e53d1">);
    }

    </span><span style="color: #400080">while </span><span style="color: #2e53d1">(</span><span style="color: #259241">1</span><span style="color: #2e53d1">)
    {
        </span><span style="color: #400080">char </span>recvmsg<span style="color: #2e53d1">[</span><span style="color: #259241">256</span><span style="color: #2e53d1">] = {</span><span style="color: #259241">0</span><span style="color: #2e53d1">};
        </span><span style="color: #400080">if </span><span style="color: #2e53d1">((</span>recvbytes <span style="color: #2e53d1">= </span>recv<span style="color: #2e53d1">(</span>serverSockfd<span style="color: #2e53d1">, </span>recvmsg<span style="color: #2e53d1">, </span><span style="color: #259241">256</span><span style="color: #2e53d1">, </span><span style="color: #259241">0</span><span style="color: #2e53d1">)) == -</span><span style="color: #259241">1</span><span style="color: #2e53d1">)
        {
            </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"recv msg: %s error\n"</span><span style="color: #2e53d1">, </span>recvmsg<span style="color: #2e53d1">);
            </span>exit<span style="color: #2e53d1">(</span><span style="color: #259241">1</span><span style="color: #2e53d1">);
        }
        </span><span style="color: #400080">else
        </span><span style="color: #2e53d1">{
            </span>recvmsg<span style="color: #2e53d1">[</span>recvbytes<span style="color: #2e53d1">] = </span><span style="color: #259241">'\0'</span><span style="color: #2e53d1">;
            </span><span style="color: #400080">if </span><span style="color: #2e53d1">(</span>strcmp<span style="color: #2e53d1">(</span>recvmsg<span style="color: #2e53d1">, </span><span style="color: #259241">"greedisgood"</span><span style="color: #2e53d1">) == </span><span style="color: #259241">0</span><span style="color: #2e53d1">)
            {
                </span>send<span style="color: #2e53d1">(</span>serverSockfd<span style="color: #2e53d1">, </span><span style="color: #259241">"greedisgood"</span><span style="color: #2e53d1">, </span><span style="color: #259241">12</span><span style="color: #2e53d1">, </span><span style="color: #259241">0</span><span style="color: #2e53d1">);
                </span><span style="color: #400080">break</span><span style="color: #2e53d1">;
            }
            </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"says: %s\n"</span><span style="color: #2e53d1">, </span>recvmsg<span style="color: #2e53d1">);
            </span><span style="color: #400080">char </span>sendmsg<span style="color: #2e53d1">[</span><span style="color: #259241">256</span><span style="color: #2e53d1">] = {</span><span style="color: #259241">0</span><span style="color: #2e53d1">};
            </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"&gt;: "</span><span style="color: #2e53d1">);
            </span>gets<span style="color: #2e53d1">(</span>sendmsg<span style="color: #2e53d1">);
            </span><span style="color: #400080">if </span><span style="color: #2e53d1">(</span>send<span style="color: #2e53d1">(</span>serverSockfd<span style="color: #2e53d1">, </span>sendmsg<span style="color: #2e53d1">, </span><span style="color: #400080">sizeof</span><span style="color: #2e53d1">(</span>sendmsg<span style="color: #2e53d1">), </span><span style="color: #259241">0</span><span style="color: #2e53d1">) == -</span><span style="color: #259241">1</span><span style="color: #2e53d1">)
            {
                </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"send msg: %s error\n"</span><span style="color: #2e53d1">, </span>sendmsg<span style="color: #2e53d1">);
                </span>exit<span style="color: #2e53d1">(</span><span style="color: #259241">1</span><span style="color: #2e53d1">);
            }
        }

    }

    </span>close<span style="color: #2e53d1">(</span>serverSockfd<span style="color: #2e53d1">);

    </span><span style="color: #400080">return </span><span style="color: #259241">0</span><span style="color: #2e53d1">;
}

</span></pre>
</span><span style="color: #2e53d1">其中says开始即为对方说的话，而&gt;:则为自己收入的内容
</span></pre>
<p>实例：</p>
<p>server端：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; client端：</p>
<p><a href="http://www.cppblog.com/images/cppblog_com/izualzhy/Windows-Live-Writer/socket_EC88/image_2.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.cppblog.com/images/cppblog_com/izualzhy/Windows-Live-Writer/socket_EC88/image_thumb.png" width="463" height="236"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://www.cppblog.com/images/cppblog_com/izualzhy/Windows-Live-Writer/socket_EC88/image_4.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.cppblog.com/images/cppblog_com/izualzhy/Windows-Live-Writer/socket_EC88/image_thumb_1.png" width="476" height="240"></a></p><img src ="http://www.cppblog.com/izualzhy/aggbug/186269.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/izualzhy/" target="_blank">izualzhy</a> 2012-08-04 17:15 <a href="http://www.cppblog.com/izualzhy/archive/2012/08/04/186269.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于in_addr,inet_addr,inet_ntoa的简单介绍</title><link>http://www.cppblog.com/izualzhy/archive/2012/08/04/186250.html</link><dc:creator>izualzhy</dc:creator><author>izualzhy</author><pubDate>Sat, 04 Aug 2012 05:30:00 GMT</pubDate><guid>http://www.cppblog.com/izualzhy/archive/2012/08/04/186250.html</guid><wfw:comment>http://www.cppblog.com/izualzhy/comments/186250.html</wfw:comment><comments>http://www.cppblog.com/izualzhy/archive/2012/08/04/186250.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/izualzhy/comments/commentRss/186250.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/izualzhy/services/trackbacks/186250.html</trackback:ping><description><![CDATA[<div style="padding: 0px; margin: 0px; display: inline; float: none; " id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:b5393cab-aafa-454b-95ae-5f336cb462f6" class="wlWriterEditableSmartContent">Technorati 标签: <a href="http://technorati.com/tags/socket" rel="tag">socket</a></div> <p>在这里<a href="http://www.cppblog.com/izualzhy/archive/2012/07/28/185459.html">http://www.cppblog.com/izualzhy/archive/2012/07/28/185459.html</a>介绍了两个结构体</p> <p>struct sockaddr与struct sockaddr_in的关系和区别。</p> <p>其中struct sockaddr_in有一个成员为</p> <p>struct in_addr sin_addr;//Internet地址</p> <p>原文里关于该结构体做了足够的说明：</p> <p>而struct in_addr的定义如下（unix）：<br />typedef uint32_t in_addr_t; </p><p>struct in_addr { </p><p>in_addr_t s_addr; </p><p>}; </p><p><strong>那么该结构体到底如何使用的？该如何赋值？</strong> </p><p>这里就用得到inet_addr()了，该函数用于将形如&#8221;192.168.1.1&#8221;的ip地址字符串转化为 </p><p>in_addr_t的形式(实际上就是uint32_t,即unsigned long). </p><p align="left">例如192对应的16进制为c0,168(a8). </p><p align="left">逆过程则用inet_ntoa实现。 </p><p align="left">直接看个例子和运行结果，一目了然~</p><pre class="code"><span style="color: #937a42">/*
 * =====================================================================================
 *       Filename:  test.c
 *    Description:  sample of inet_ntoa,inet_addr 
 *        Created:  08/04/2012 01:23:39 PM
 *         Author:  zhy (), izualzhy@163.com
 * =====================================================================================
 */
</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;stdio.h&gt;
</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;netinet/in.h&gt;

</span><span style="color: #400080">int </span>main<span style="color: #2e53d1">()
{
    </span><span style="color: #400080">struct </span>in_addr addr<span style="color: #2e53d1">;
    </span><span style="color: #400080">char</span><span style="color: #2e53d1">* </span>straddr <span style="color: #2e53d1">= </span>malloc<span style="color: #2e53d1">(</span><span style="color: #259241">16</span><span style="color: #2e53d1">*</span><span style="color: #400080">sizeof</span><span style="color: #2e53d1">(</span><span style="color: #400080">char</span><span style="color: #2e53d1">));
    </span>memset<span style="color: #2e53d1">(</span>straddr<span style="color: #2e53d1">, </span><span style="color: #259241">0</span><span style="color: #2e53d1">, </span><span style="color: #259241">16</span><span style="color: #2e53d1">);

    </span>addr<span style="color: #2e53d1">.</span>s_addr <span style="color: #2e53d1">= </span>inet_addr<span style="color: #2e53d1">(</span><span style="color: #259241">"192.168.1.1"</span><span style="color: #2e53d1">);
    </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"%x\n"</span><span style="color: #2e53d1">,</span>addr<span style="color: #2e53d1">.</span>s_addr<span style="color: #2e53d1">);
    </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"%s\n"</span><span style="color: #2e53d1">,</span>inet_ntoa<span style="color: #2e53d1">(</span>addr<span style="color: #2e53d1">));

    </span>addr<span style="color: #2e53d1">.</span>s_addr <span style="color: #2e53d1">= </span>inet_addr<span style="color: #2e53d1">(</span><span style="color: #259241">"172.27.1.1"</span><span style="color: #2e53d1">);
    </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"%x\n"</span><span style="color: #2e53d1">,</span>addr<span style="color: #2e53d1">.</span>s_addr<span style="color: #2e53d1">);
    </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"%s\n"</span><span style="color: #2e53d1">,</span>inet_ntoa<span style="color: #2e53d1">(</span>addr<span style="color: #2e53d1">));

    </span>addr<span style="color: #2e53d1">.</span>s_addr <span style="color: #2e53d1">= </span>inet_addr<span style="color: #2e53d1">(</span><span style="color: #259241">"255.255.255.255"</span><span style="color: #2e53d1">);
    </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"%x, %d\n"</span><span style="color: #2e53d1">,</span>addr<span style="color: #2e53d1">.</span>s_addr<span style="color: #2e53d1">,</span>addr<span style="color: #2e53d1">.</span>s_addr<span style="color: #2e53d1">);
    </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"%s\n"</span><span style="color: #2e53d1">,</span>inet_ntoa<span style="color: #2e53d1">(</span>addr<span style="color: #2e53d1">));

    </span><span style="color: #400080">return </span><span style="color: #259241">0</span><span style="color: #2e53d1">;
}

</span></pre>
<p align="left"><strong>结果：</strong>
</p><p>y@y-VirtualBox:/mnt/Documents/Training$ ./test<br />101a8c0<br />192.168.1.1<br />1011bac<br />172.27.1.1<br />ffffffff, -1<br />255.255.255.255</p>
<p align="left">同时可以<font color="#ff0000">注意</font>到：
</p><p>inet_addr()返回的地址已经是网络字节格式，所以你无需再调用 函数htonl()。<br />我们现在发现上面的代码片断不是十分完整的，因为它没有错误检查。 显而易见，当inet_addr()发生错误时返回-1。记住这些二进制数字？(无符 号数)-1仅仅和IP地址255.255.255.255相符合！这可是广播地址！大错特 错！记住要先进行错误检查。
</p><p align="left">而inet_adder的manpage里也提到了：
</p><p>The inet_addr() function converts the Internet&nbsp; host&nbsp; address&nbsp; cp&nbsp; from<br />IPv4&nbsp; numbers-and-dots notation into binary data in network byte order.<br />If the input is invalid, INADDR_NONE (usually -1) is returned.&nbsp; Use&nbsp; of<br />this&nbsp;&nbsp; function&nbsp;&nbsp; is&nbsp;&nbsp; problematic&nbsp;&nbsp; because&nbsp; -1&nbsp; is&nbsp; a&nbsp; valid&nbsp; address<br />(255.255.255.255).&nbsp;&nbsp; Avoid&nbsp;&nbsp; its&nbsp;&nbsp; use&nbsp;&nbsp; in&nbsp;&nbsp; favor&nbsp;&nbsp; of&nbsp;&nbsp; inet_aton(),<br />inet_pton(3), or getaddrinfo(3) which provide a cleaner way to indicate<br />error return.<br /><br />ps:<br />我这里比较好奇的是，inet_ntoa返回一个char*而外部可以直接使用又不需要free，是如何做到的?</p><img src ="http://www.cppblog.com/izualzhy/aggbug/186250.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/izualzhy/" target="_blank">izualzhy</a> 2012-08-04 13:30 <a href="http://www.cppblog.com/izualzhy/archive/2012/08/04/186250.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>socket常用的struct sockaddr与struct sockaddr_in</title><link>http://www.cppblog.com/izualzhy/archive/2012/07/28/185459.html</link><dc:creator>izualzhy</dc:creator><author>izualzhy</author><pubDate>Sat, 28 Jul 2012 08:27:00 GMT</pubDate><guid>http://www.cppblog.com/izualzhy/archive/2012/07/28/185459.html</guid><wfw:comment>http://www.cppblog.com/izualzhy/comments/185459.html</wfw:comment><comments>http://www.cppblog.com/izualzhy/archive/2012/07/28/185459.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/izualzhy/comments/commentRss/185459.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/izualzhy/services/trackbacks/185459.html</trackback:ping><description><![CDATA[<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:48661474-f8cc-4daf-bca1-703261267b7f" class="wlWriterEditableSmartContent">Technorati 标签: <a href="http://technorati.com/tags/socket" rel="tag">socket</a></div> <p>在前面的socket介绍里经常出现两种结构体：</p> <p>struct sockaddr;</p> <p>struct sockaddr_in;</p> <p>在&lt;sys/socket.h&gt;里定义：</p> <p>struct sockaddr { <br>　　 unsigned short sa_family; /* 地址家族, AF_xxx */ <br>　　 char sa_data[14]; /*14字节协议地址*/ <br>　　 };&nbsp; <p>为了处理struct sockaddr，程序员创造了一个并列的结构： struct sockaddr_in ("in" 代表 "Internet"。)</p> <p>在&lt;netinte/in.h&gt;里定义：<br>struct sockaddr_in { <br>　　 short int sin_family; /* 通信类型 */ <br>　　 unsigned short int sin_port; /* 端口 */ <br>　　 struct in_addr sin_addr; /* Internet 地址 */ <br>　　 unsigned char sin_zero[8]; /* 与sockaddr结构的长度相同*/ <br>　　 }; </p> <p>用这个结构可以更轻松的处理套接字地址的基本元素。</p> <p>sin_zero的加入使得这两个结构体size相同（16），应该使用函数bzero(),memset()置为0.</p> <p>而struct in_addr的定义如下（unix）：<br>typedef uint32_t in_addr_t;</p> <p>struct in_addr {</p> <p>in_addr_t s_addr;</p> <p>};</p> <p>指向sockaddr_in 的指针和指向sockaddr的指针可以相互转换，这意味着如果一个函数所需参数类型是sockaddr时，你可以在函数调用的时候将一个指向 sockaddr_in的指针转换为指向sockaddr的指针；或者相反。</p> <p>使用bind函数时，可以用下面的赋值实现自动获得本机IP地址和随机获取一个没有被占用的端口号：<br>　　 my_addr.sin_port = 0; /* 系统随机选择一个未被使用的端口号 */<br>　　 my_addr.sin_addr.s_addr = INADDR_ANY; /* 填入本机IP地址 */<br>通过将my_addr.sin_port置为0，函数会自动为你选择一个未占用的端口来使用。同样，通过将my_addr.sin_addr.s_addr置为INADDR_ANY，系统会自动填入本机IP地址。<br>注意在使用bind函数是需要将sin_port和sin_addr转换成为网络字节优先顺序；而sin_addr则不需要转换。<br>　　计算机数据存储有两种字节优先顺序：高位字节优先和低位字节优先。Internet上数据以高位字节优先顺序在网络上传输，所以对于在内部是以低位字节优先方式存储数据的机器，在Internet上传输数据时就需要进行转换，否则就会出现数据不一致。<br>　　 下面是几个字节顺序转换函数：<br>·htonl()：把32位值从主机字节序转换成网络字节序<br>·htons()：把16位值从主机字节序转换成网络字节序<br>·ntohl()：把32位值从网络字节序转换成主机字节序<br>·ntohs()：把16位值从网络字节序转换成主机字节序</p><img src ="http://www.cppblog.com/izualzhy/aggbug/185459.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/izualzhy/" target="_blank">izualzhy</a> 2012-07-28 16:27 <a href="http://www.cppblog.com/izualzhy/archive/2012/07/28/185459.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>socket接口简介</title><link>http://www.cppblog.com/izualzhy/archive/2012/07/28/185454.html</link><dc:creator>izualzhy</dc:creator><author>izualzhy</author><pubDate>Sat, 28 Jul 2012 07:52:00 GMT</pubDate><guid>http://www.cppblog.com/izualzhy/archive/2012/07/28/185454.html</guid><wfw:comment>http://www.cppblog.com/izualzhy/comments/185454.html</wfw:comment><comments>http://www.cppblog.com/izualzhy/archive/2012/07/28/185454.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/izualzhy/comments/commentRss/185454.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/izualzhy/services/trackbacks/185454.html</trackback:ping><description><![CDATA[<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:bc5139ba-1c56-4c2d-913c-5bc8865389d9" class="wlWriterEditableSmartContent">Technorati 标签: <a href="http://technorati.com/tags/socket" rel="tag">socket</a></div> <p><font color="#ff0000" size="3"><strong>1</strong></font><font color="#ff0000" size="3"><strong>.SOCKET建立</strong></font></p> <p><font color="#0000ff" size="3">原型：</font></p> <p><font size="3">int socket(int domain, int type, int protocol)</font></p> <p><font color="#0000ff" size="3">参数：</font></p> <p><font size="3">domain:所使用的协议族，通常为AF_INET<br>type:socket类型，SOCK_STREAM,SOCK_DGRAM,socket还定义了原始的Socket(SOCK_RAW)</font></p> <p><font size="3">protocol:通常为0</font></p> <p><font color="#0000ff" size="3">解释：</font></p> <p><font size="3">Socket()调用返回一个整型socket描述符，你可以在后面的调用使用它。<br>Socket描述符是一个指向内部数据结构的指针，它指向描述符表入口。调用Socket函数时，socket执行体将建立一个Socket，实际上"建立一个Socket"意味着为一个Socket数据结构分配存储空间。Socket执行体为你管理描述符表。<br>两个网络程序之间的一个网络连接包括五种信息：通信协议、本地协议地址、本地主机端口、远端主机地址和远端协议端口。Socket数据结构中包含这五种信息。</font></p> <p><font color="#ff0000" size="3"><strong>2.SOCKET配置</strong></font></p> <p><font color="#0000ff" size="3">原型：</font></p> <p><font size="3">int bind(int sockfd, struct sockaddr* my_addr, int addrlen);</font></p> <p><font color="#0000ff" size="3">参数：</font></p> <p><font size="3">sockfd:调用socket()返回的socket描述符</font></p> <p><font size="3">my_addr:只想包含有本地IP地址及端口号等信息的sockaddr类型的指针；</font></p> <p><font size="3">addrlen:通常设置为sizeof(struct sockaddr)</font></p> <p><font color="#0000ff" size="3">解释：</font></p> <p><font size="3">通过socket调用返回一个socket描述符后，在使用socket进行网络传输以前，必须配置该socket。面向连接的socket客户端通过 调用Connect函数在socket数据结构中保存本地和远端信息。无连接socket的客户端和服务端以及面向连接socket的服务端通过调用 bind函数来配置本地信息。<br>Bind函数将socket与本机上的一个端口相关联，随后你就可以在该端口监听服务请求。</font> <p><font size="3">Bind()函数在成功被调用时返回0；出现错误时返回"-1"并将errno置为相应的错误号。需要注意的是，在调用bind函数时一般不要将端口号置为小于1024的值，因为1到1024是保留端口号，你可以选择大于1024中的任何一个没有被占用的端口号。</font> <p><font color="#ff0000" size="3"><strong>3.建立连接</strong></font></p> <p><font color="#0000ff" size="3">原型：</font></p> <p><font size="3">int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);</font></p> <p><font color="#0000ff" size="3">参数：</font></p> <p><font size="3">sockfd:调用socket()返回的socket描述符</font></p> <p><font size="3">serv_addr:包含远端主机IP地址和端口号的指针</font></p> <p><font size="3">addrlen:远端地址结构的长度</font></p> <p><font color="#0000ff" size="3">解释：</font></p> <p><font size="3">Connect函数在出现错误时返回-1，并且设置errno为相应的错误码。进行客户端程序设计无须调用bind()，因为这种情况下只需知道目的机器 的IP地址，而客户通过哪个端口与服务器建立连接并不需要关心，socket执行体为你的程序自动选择一个未被占用的端口，并通知你的程序数据什么时候到 打断口。<br>Connect函数启动和远端主机的直接连接。只有面向连接的客户程序使用socket时才需要将此socket与远端主机相连。无连接协议从不建立直接连接。面向连接的服务器也从不启动一个连接，它只是被动的在协议端口监听客户的请求。</font> <p><font color="#ff0000" size="3"><strong>4.监听模式</strong></font></p> <p><font color="#0000ff" size="3">原型：</font></p> <p><font size="3">int listen(int sockfd, int backlog);</font></p> <p><font color="#0000ff" size="3">参数：</font></p> <p><font size="3">sockfd： socket函数调用返回的socket描述符；</font></p> <p><font size="3">backlog： 在请求队列中允许的最大请求数，进入的连接请求将在队列中等待accept()它们。Backlog对队列中等待 服务的请求的数目进行了限制，大多数系统缺省值为20。如果一个服务请求到来时，输入队列已满，该socket将拒绝连接请求，客户将收到一个出错信息。</font></p> <p><font color="#0000ff" size="3">解释：</font></p> <p><font size="3">Listen函数使socket处于被动的监听模式，并为该socket建立一个输入数据队列，将到达的服务请求保存在此队列中，直到程序处理它们。</font></p> <p><font size="3">当出现错误时listen函数返回-1，并置相应的errno错误码。</font></p> <p><font color="#ff0000" size="3"><strong>5.接收连接请求</strong></font></p> <p><font color="#0000ff" size="3">原型：</font></p> <p><font size="3">int accept(int sockfd, void *addr, int *addrlen);</font></p> <p><font color="#0000ff" size="3">参数：</font></p> <p><font size="3">sockfd： 被监听的socket描述符</font></p> <p><font size="3">addr： 通常是一个指向sockaddr_in的指针，改变量用来存放提出连接请求服务的主机的信息（某台主机从某个端口发出该请求）</font></p> <p><font size="3">addrlen： 通常为sizeof(struct sockaddr_in)</font></p> <p><font color="#0000ff" size="3">解释：</font></p> <p><font size="3">accept()函数让服务器接收客户的连接请求。在建立好输入队列后，服务器就调用accept函数，然后睡眠并等待客户的连接请求。</font></p> <p><font size="3">出现错误时accept函数返回-1并置相应的errno值。</font></p> <p><font size="3">首先，当accept函数监视的 socket收到连接请求时，socket执行体将建立一个新的socket，执行体将这个新socket和请求连接进程的地址联系起来，收到服务请求的 初始socket仍可以继续在以前的 socket上监听，同时可以在新的socket描述符上进行数据传输操作。</font></p> <p><font color="#ff0000" size="3"><strong>6.数据传输</strong></font></p> <p><font size="3">Send()和recv()这两个函数用于面向连接的socket上进行数据传输。</font></p> <p><font color="#0000ff" size="3">原型：</font></p> <p><font size="3">int send(int sockfd, const void* msg, int len, unsigned int flags);</font></p> <p><font color="#0000ff" size="3">参数：</font></p> <p><font size="3">sockfd:用来传输数据的socket描述符</font></p> <p><font size="3">msg：指向要发送数据的指针</font></p> <p><font size="3">len：以字节为单位的数据的长度</font></p> <p><font size="3">flags：一般情况下置为0</font></p> <p><font color="#0000ff" size="3">解释：</font></p> <p><font size="3">Send()函数返回实际上发送出的字节数，可能会少于你希望发送的数据。在程序中应该将send()的返回值与欲发送的字节数进行比较。</font></p> <p><font color="#0000ff" size="3">原型：</font></p> <p><font size="3">int recv(int sockfd, void* buf, int len, unsigned int flags);</font></p> <p><font color="#0000ff" size="3">参数：</font></p> <p><font size="3">sockfd:接受数据的socket描述符</font></p> <p><font size="3">buf:存放接受数据的缓冲区</font></p> <p><font size="3">len：缓冲的长度</font></p> <p><font size="3">flags：通常置为0</font></p> <p><font color="#0000ff" size="3">解释：</font></p> <p><font size="3">Recv()返回实际上接收的字节数，当出现错误时，返回-1并置相应的errno值。</font></p> <p><font size="3">Sendto()和recvfrom()用于在无连接的数据报socket方式下进行数据传输。由于本地socket并没有与远端机器建立连接，所以在发送数据时应指明目的地址。</font></p> <p><font color="#0000ff" size="3">原型：</font></p> <p><font size="3">int sendto(int sockfd, const void* msg, int len, unsigned int flags, const struct sockaddr* to, int tolen);</font></p> <p><font size="3">比sendto多了两个参数：</font></p> <p><font size="3">to:目的机的IP地址和端口号信息</font></p> <p><font size="3">tolen：通常为sizeof(struct sockaddr)</font></p> <p><font color="#0000ff" size="3">解释：</font></p> <p><font size="3">Sendto 函数也返回实际发送的数据字节长度或在出现发送错误时返回-1。</font></p> <p><font size="3">原型：</font></p> <p><font size="3">int recvfrom(int sockfd, void *buf, int len, unsigned int flags, struct sockaddr* from, int *fromlen);</font></p> <p><font color="#0000ff" size="3">参数：</font></p> <p><font size="3">from:保存源机的IP地址以及端口号</font></p> <p><font size="3">fromlen:通常为sizeof(struct sockaddr)，当recvfrom()返回时，fromlen包含实际存入from中的数据字节数。</font></p> <p><font color="#0000ff" size="3">解释：</font></p> <p><font size="3">Recvfrom()函数返回接收到的字节数或 当出现错误时返回-1，并置相应的errno。</font></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3">如果你对数据报socket调用了connect()函数时，你也可以利用send()和recv()进行数据传输，但该socket仍然是数据报socket，并且利用传输层的UDP服务。但在发送或接收数据报时，内核会自动为之加上目地和源地址信息。</font></p> <p><font color="#ff0000" size="3"><strong>7.结束传输</strong></font></p> <p><font color="#0000ff" size="3">原型：</font></p> <p><font size="3">close(sockfd);</font></p> <p><font color="#0000ff" size="3">解释：</font></p> <p><font size="3">当所有的数据操作结束以后，你可以调用close()函数来释放该socket，从而停止在该socket上的任何数据操作。</font></p> <p><font size="3">int shutdown(int sockfd, int how);</font></p> <p><font color="#0000ff" size="3">解释：</font></p> <p><font size="3">你也可以调用shutdown()函数来关闭该socket。该函数允许你只停止在某个方向上的数据传输，而一个方向上的数据传输继续进行。如你可以关闭某socket的写操作而允许继续在该socket上接受数据，直至读入所有数据。<br>Sockfd是需要关闭的socket的描述符。参数 how允许为shutdown操作选择以下几种方式：<br>　　 ·0-------不允许继续接收数据<br>　　 ·1-------不允许继续发送数据<br>　　 ·2-------不允许继续发送和接收数据，<br>　　 ·均为允许则调用close ()<br>shutdown在操作成功时返回0，在出现错误时返回-1并置相应errno。</font> <p><font size="3"></font>&nbsp;</p> <p><font size="3">接下来看这里，是不是就好理解多了？</font></p> <p><a href="http://www.cppblog.com/izualzhy/archive/2012/07/28/185451.html">http://www.cppblog.com/izualzhy/archive/2012/07/28/185451.html</a></p> <p><font size="3">参考：</font></p> <p><a href="http://www.kuqin.com/networkprog/20080512/8361.html"><font size="3">http://www.kuqin.com/networkprog/20080512/8361.html</font></a></p> <p><font size="3"></font>&nbsp;</p> <p><font size="3"></font>&nbsp;</p> <p><font size="3"></font>&nbsp;</p> <p><font size="3"></font></p><img src ="http://www.cppblog.com/izualzhy/aggbug/185454.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/izualzhy/" target="_blank">izualzhy</a> 2012-07-28 15:52 <a href="http://www.cppblog.com/izualzhy/archive/2012/07/28/185454.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>socket学习笔记一之实例入门</title><link>http://www.cppblog.com/izualzhy/archive/2012/07/28/185451.html</link><dc:creator>izualzhy</dc:creator><author>izualzhy</author><pubDate>Sat, 28 Jul 2012 06:17:00 GMT</pubDate><guid>http://www.cppblog.com/izualzhy/archive/2012/07/28/185451.html</guid><wfw:comment>http://www.cppblog.com/izualzhy/comments/185451.html</wfw:comment><comments>http://www.cppblog.com/izualzhy/archive/2012/07/28/185451.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/izualzhy/comments/commentRss/185451.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/izualzhy/services/trackbacks/185451.html</trackback:ping><description><![CDATA[<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:b96e47d4-d079-473b-9bfa-304e959a8cef" class="wlWriterEditableSmartContent">Technorati 标签: <a href="http://technorati.com/tags/socket" rel="tag">socket</a></div> <p>不知道为什么，从网上搜到的关于socket的文章都无一例外的提到socket编程很简单，如果你了解了以后。。。</p> <p>我在学习中发现并不是这么简单的，一步一步学习了呵呵。先放个流程，以及例子：</p> <p><img src="http://www.kuqin.com/networkprog/images/socket3.jpg"></p> <p>代码基本按照这个流程来的，什么socket，bind，AF_INET大概理解的就先理解着，不理解也没问题。我的理解是这只是冰山一角，有SOCKET_STREAM,还有SOCKET_DGRAM呢，一点点学习理解与积累吧。<br>我相信等记上几篇笔记后，整个代码在干什么会很容易理解的了。</p> <p>而大部分人说的socket编程容易应该是流程比较清晰，不过其中的函数接口，类型等等，还是需要仔细琢磨的。</p> <p>废话不多讲了，贴个例子，运行下才好。</p> <p>开两个终端，一个运行server，一个client即可。</p> <p>至于client的参数，不妨自己考虑下，毕竟学习的过程肯定要耗费脑细胞的^_^</p> <p>服务器：</p><pre class="code"><span style="color: #937a42">/*
 * =====================================================================================
 *       Filename:  svr.c
 *    Description:  socket server
 *
 *        Version:  1.0
 *        Created:  07/28/2012 12:46:39 PM
 *
 *         Author:  zhy (), izualzhy@163.com
 * =====================================================================================
 */

</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;stdio.h&gt;
</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;stdlib.h&gt;
</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;errno.h&gt;
</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;string.h&gt;
</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;sys/types.h&gt;
</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;netinet/in.h&gt;
</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;sys/socket.h&gt;
</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;sys/wait.h&gt;

</span><span style="color: #400080">#define </span>SERVPORT <span style="color: #259241">3333
</span><span style="color: #400080">#define </span>BACKLOG <span style="color: #259241">10

</span><span style="color: #400080">int </span>main<span style="color: #2e53d1">()
{
    </span><span style="color: #400080">int </span>sockfd<span style="color: #2e53d1">, </span>client_fd<span style="color: #2e53d1">;</span><span style="color: #937a42">//sockfd:监听socket，chient_fd:数据传输socket
    </span><span style="color: #400080">struct </span>sockaddr_in my_addr<span style="color: #2e53d1">;</span><span style="color: #937a42">//本地地址信息
    </span><span style="color: #400080">struct </span>sockaddr_in remote_addr<span style="color: #2e53d1">;
    </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"sockaddr: %d, sockaddr_in: %d\n"</span><span style="color: #2e53d1">,</span><span style="color: #400080">sizeof</span><span style="color: #2e53d1">(</span><span style="color: #400080">struct </span>sockaddr<span style="color: #2e53d1">), </span><span style="color: #400080">sizeof</span><span style="color: #2e53d1">(</span><span style="color: #400080">struct </span>sockaddr_in<span style="color: #2e53d1">));

    </span><span style="color: #400080">if </span><span style="color: #2e53d1">((</span>sockfd <span style="color: #2e53d1">= </span>socket<span style="color: #2e53d1">(</span>AF_INET<span style="color: #2e53d1">, </span>SOCK_STREAM<span style="color: #2e53d1">, </span><span style="color: #259241">0</span><span style="color: #2e53d1">)) == -</span><span style="color: #259241">1</span><span style="color: #2e53d1">)
    {
        </span>perror<span style="color: #2e53d1">(</span><span style="color: #259241">"socket create error!"</span><span style="color: #2e53d1">);
        </span>exit<span style="color: #2e53d1">(</span><span style="color: #259241">1</span><span style="color: #2e53d1">);
    }

    </span>my_addr<span style="color: #2e53d1">.</span>sin_family <span style="color: #2e53d1">= </span>AF_INET<span style="color: #2e53d1">;
    </span>my_addr<span style="color: #2e53d1">.</span>sin_port <span style="color: #2e53d1">= </span>htons<span style="color: #2e53d1">(</span>SERVPORT<span style="color: #2e53d1">);
    </span>my_addr<span style="color: #2e53d1">.</span>sin_addr<span style="color: #2e53d1">.</span>s_addr <span style="color: #2e53d1">= </span>INADDR_ANY<span style="color: #2e53d1">;
    </span>bzero<span style="color: #2e53d1">(&amp;</span>my_addr<span style="color: #2e53d1">.</span>sin_zero<span style="color: #2e53d1">, </span><span style="color: #259241">8</span><span style="color: #2e53d1">);

    </span><span style="color: #400080">if </span><span style="color: #2e53d1">(</span>bind<span style="color: #2e53d1">(</span>sockfd<span style="color: #2e53d1">, (</span><span style="color: #400080">struct </span>sockaddr<span style="color: #2e53d1">*)&amp;</span>my_addr<span style="color: #2e53d1">, </span><span style="color: #400080">sizeof</span><span style="color: #2e53d1">(</span><span style="color: #400080">struct </span>sockaddr<span style="color: #2e53d1">)) == -</span><span style="color: #259241">1</span><span style="color: #2e53d1">)
    {
        </span>perror<span style="color: #2e53d1">(</span><span style="color: #259241">"bind error!"</span><span style="color: #2e53d1">);
        </span>exit<span style="color: #2e53d1">(</span><span style="color: #259241">1</span><span style="color: #2e53d1">);
    }

    </span><span style="color: #400080">if </span><span style="color: #2e53d1">(</span>listen<span style="color: #2e53d1">(</span>sockfd<span style="color: #2e53d1">, </span>BACKLOG<span style="color: #2e53d1">) == -</span><span style="color: #259241">1</span><span style="color: #2e53d1">)
    {
        </span>perror<span style="color: #2e53d1">(</span><span style="color: #259241">"listen error!"</span><span style="color: #2e53d1">);
        </span>exit<span style="color: #2e53d1">(</span><span style="color: #259241">1</span><span style="color: #2e53d1">);
    }

    </span><span style="color: #400080">while </span><span style="color: #2e53d1">(</span><span style="color: #259241">1</span><span style="color: #2e53d1">)
    {
        </span><span style="color: #400080">unsigned int </span>sin_size <span style="color: #2e53d1">= </span><span style="color: #400080">sizeof</span><span style="color: #2e53d1">(</span><span style="color: #400080">struct </span>sockaddr_in<span style="color: #2e53d1">);
        </span><span style="color: #400080">if </span><span style="color: #2e53d1">((</span>client_fd <span style="color: #2e53d1">= </span>accept<span style="color: #2e53d1">(</span>sockfd<span style="color: #2e53d1">, (</span><span style="color: #400080">struct </span>sockaddr<span style="color: #2e53d1">*)&amp;</span>remote_addr<span style="color: #2e53d1">, &amp;</span>sin_size<span style="color: #2e53d1">)) == -</span><span style="color: #259241">1</span><span style="color: #2e53d1">)
        {
            </span>perror<span style="color: #2e53d1">(</span><span style="color: #259241">"accept erro!"</span><span style="color: #2e53d1">);
            </span><span style="color: #400080">continue</span><span style="color: #2e53d1">;
        }

        </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"received a connection from %s\n"</span><span style="color: #2e53d1">, </span>inet_ntoa<span style="color: #2e53d1">(</span>remote_addr<span style="color: #2e53d1">.</span>sin_addr<span style="color: #2e53d1">));

        </span><span style="color: #400080">if </span><span style="color: #2e53d1">(!</span>fork<span style="color: #2e53d1">())
        {
            </span><span style="color: #400080">if </span><span style="color: #2e53d1">(</span>send<span style="color: #2e53d1">(</span>client_fd<span style="color: #2e53d1">, </span><span style="color: #259241">"Hello, you are connected!"</span><span style="color: #2e53d1">, </span><span style="color: #259241">26</span><span style="color: #2e53d1">, </span><span style="color: #259241">0</span><span style="color: #2e53d1">) == -</span><span style="color: #259241">1</span><span style="color: #2e53d1">)
            {
                </span>perror<span style="color: #2e53d1">(</span><span style="color: #259241">"send error!"</span><span style="color: #2e53d1">);
                </span>close<span style="color: #2e53d1">(</span>client_fd<span style="color: #2e53d1">);
                </span>exit<span style="color: #2e53d1">(</span><span style="color: #259241">0</span><span style="color: #2e53d1">);
            }
        }
        </span>close<span style="color: #2e53d1">(</span>client_fd<span style="color: #2e53d1">);
    }

    </span><span style="color: #400080">return </span><span style="color: #259241">0</span><span style="color: #2e53d1">;
}

</span></pre>
<p>客户端：</p><pre class="code"><span style="color: #937a42">/*
 * =====================================================================================
 *       Filename:  clnt.c
 *    Description:  socket client
 *
 *        Version:  1.0
 *        Created:  07/28/2012 01:00:46 PM
 *
 *         Author:  zhy (), izualzhy@163.com
 * =====================================================================================
 */

</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;stdio.h&gt;
</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;stdlib.h&gt;
</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;errno.h&gt;
</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;string.h&gt;
</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;netdb.h&gt;
</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;sys/types.h&gt;
</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;netinet/in.h&gt;
</span><span style="color: #400080">#include </span><span style="color: #259241">&lt;sys/socket.h&gt;
</span><span style="color: #400080">#define </span>SERVPORT <span style="color: #259241">3333
</span><span style="color: #400080">#define </span>MAXDATASIZE <span style="color: #259241">100</span><span style="color: #937a42">//每次最大数据传输量

</span><span style="color: #400080">int </span>main<span style="color: #2e53d1">(</span><span style="color: #400080">int </span>argc<span style="color: #2e53d1">, </span><span style="color: #400080">char</span><span style="color: #2e53d1">* </span>argv<span style="color: #2e53d1">[])
{
    </span><span style="color: #400080">int </span>sockfd<span style="color: #2e53d1">, </span>recvbytes<span style="color: #2e53d1">;
    </span><span style="color: #400080">char </span>buf<span style="color: #2e53d1">[</span>MAXDATASIZE<span style="color: #2e53d1">];
    </span><span style="color: #400080">struct </span>hostent<span style="color: #2e53d1">* </span>host<span style="color: #2e53d1">;
    </span><span style="color: #400080">struct </span>sockaddr_in serv_addr<span style="color: #2e53d1">;

    </span><span style="color: #400080">if </span><span style="color: #2e53d1">(</span>argc <span style="color: #2e53d1">&lt; </span><span style="color: #259241">2</span><span style="color: #2e53d1">)
    {
        </span>fprintf<span style="color: #2e53d1">(</span>stderr<span style="color: #2e53d1">, </span><span style="color: #259241">"Please enter the server's hostname"</span><span style="color: #2e53d1">);
        </span>exit<span style="color: #2e53d1">(</span><span style="color: #259241">1</span><span style="color: #2e53d1">);
    }

    </span><span style="color: #400080">if </span><span style="color: #2e53d1">((</span>host <span style="color: #2e53d1">= </span>gethostbyname<span style="color: #2e53d1">(</span>argv<span style="color: #2e53d1">[</span><span style="color: #259241">1</span><span style="color: #2e53d1">])) == </span>NULL<span style="color: #2e53d1">)
    {
        </span>perror<span style="color: #2e53d1">(</span><span style="color: #259241">"gethostbyname error!"</span><span style="color: #2e53d1">);
        </span>exit<span style="color: #2e53d1">(</span><span style="color: #259241">1</span><span style="color: #2e53d1">);
    }

    </span><span style="color: #400080">if </span><span style="color: #2e53d1">((</span>sockfd <span style="color: #2e53d1">= </span>socket<span style="color: #2e53d1">(</span>AF_INET<span style="color: #2e53d1">, </span>SOCK_STREAM<span style="color: #2e53d1">, </span><span style="color: #259241">0</span><span style="color: #2e53d1">)) == -</span><span style="color: #259241">1</span><span style="color: #2e53d1">)
    {
        </span>perror<span style="color: #2e53d1">(</span><span style="color: #259241">"socket create error!"</span><span style="color: #2e53d1">);
        </span>exit<span style="color: #2e53d1">(</span><span style="color: #259241">1</span><span style="color: #2e53d1">);
    }

    </span>serv_addr<span style="color: #2e53d1">.</span>sin_family <span style="color: #2e53d1">= </span>AF_INET<span style="color: #2e53d1">;
    </span>serv_addr<span style="color: #2e53d1">.</span>sin_port <span style="color: #2e53d1">= </span>htons<span style="color: #2e53d1">(</span>SERVPORT<span style="color: #2e53d1">);
    </span>serv_addr<span style="color: #2e53d1">.</span>sin_addr <span style="color: #2e53d1">= *((</span><span style="color: #400080">struct </span>in_addr <span style="color: #2e53d1">*)</span>host<span style="color: #2e53d1">-&gt;</span>h_addr<span style="color: #2e53d1">);
    </span>bzero<span style="color: #2e53d1">(&amp;(</span>serv_addr<span style="color: #2e53d1">.</span>sin_zero<span style="color: #2e53d1">), </span><span style="color: #259241">8</span><span style="color: #2e53d1">);

    </span><span style="color: #400080">if </span><span style="color: #2e53d1">(</span>connect<span style="color: #2e53d1">(</span>sockfd<span style="color: #2e53d1">, (</span><span style="color: #400080">struct </span>sockaddr<span style="color: #2e53d1">*)&amp;</span>serv_addr<span style="color: #2e53d1">, </span><span style="color: #400080">sizeof</span><span style="color: #2e53d1">(</span><span style="color: #400080">struct </span>sockaddr<span style="color: #2e53d1">)) == -</span><span style="color: #259241">1</span><span style="color: #2e53d1">)
    {
        </span>perror<span style="color: #2e53d1">(</span><span style="color: #259241">"connect error!"</span><span style="color: #2e53d1">);
        </span>exit<span style="color: #2e53d1">(</span><span style="color: #259241">1</span><span style="color: #2e53d1">);
    }

    </span><span style="color: #400080">if </span><span style="color: #2e53d1">((</span>recvbytes <span style="color: #2e53d1">= </span>recv<span style="color: #2e53d1">(</span>sockfd<span style="color: #2e53d1">, </span>buf<span style="color: #2e53d1">, </span>MAXDATASIZE<span style="color: #2e53d1">, </span><span style="color: #259241">0</span><span style="color: #2e53d1">)) == -</span><span style="color: #259241">1</span><span style="color: #2e53d1">)
    {
        </span>perror<span style="color: #2e53d1">(</span><span style="color: #259241">"recv error!"</span><span style="color: #2e53d1">);
        </span>exit<span style="color: #2e53d1">(</span><span style="color: #259241">1</span><span style="color: #2e53d1">);
    }
    </span>buf<span style="color: #2e53d1">[</span>recvbytes<span style="color: #2e53d1">] = </span><span style="color: #259241">'\0'</span><span style="color: #2e53d1">;
    </span>printf<span style="color: #2e53d1">(</span><span style="color: #259241">"Received: %s\n"</span><span style="color: #2e53d1">, </span>buf<span style="color: #2e53d1">);
    </span>close<span style="color: #2e53d1">(</span>sockfd<span style="color: #2e53d1">);

    </span><span style="color: #400080">return </span><span style="color: #259241">0</span><span style="color: #2e53d1">;
}

</span></pre>
<p>参考：</p>
<p><a href="http://www.kuqin.com/networkprog/20080512/8361.html">http://www.kuqin.com/networkprog/20080512/8361.html</a></p><img src ="http://www.cppblog.com/izualzhy/aggbug/185451.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/izualzhy/" target="_blank">izualzhy</a> 2012-07-28 14:17 <a href="http://www.cppblog.com/izualzhy/archive/2012/07/28/185451.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>