socket编程(TCP、UDP)
来源:互联网 发布:农村淘宝服务站查询 编辑:程序博客网 时间:2024/05/16 10:43
socket编程(TCP、UDP)
<div class="article_manage clearfix"> <div class="article_l"> <span class="link_categories"> 标签: <a href="http://www.csdn.net/tag/linux" target="_blank" onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_tag']);">linux</a><a href="http://www.csdn.net/tag/socket" target="_blank" onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_tag']);">socket</a><a href="http://www.csdn.net/tag/tcp" target="_blank" onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_tag']);">tcp</a><a href="http://www.csdn.net/tag/udp" target="_blank" onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_tag']);">udp</a><a href="http://www.csdn.net/tag/%e7%bd%91%e7%bb%9c" target="_blank" onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_tag']);">网络</a> </span> </div> <div class="article_r"> <span class="link_postdate">2016-01-08 15:00</span> <span class="link_view" title="阅读次数">794人阅读</span> <span class="link_comments" title="评论次数"> <a href="#comments" onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_pinglun'])">评论</a>(0)</span> <span class="link_collect tracking-ad" data-mod="popu_171"> <a href="javascript:void(0);" onclick="javascript:collectArticle('socket%e7%bc%96%e7%a8%8b%ef%bc%88TCP%e3%80%81UDP%ef%bc%89','50482959');return false;" title="收藏" target="_blank">收藏</a></span> <span class="link_report"> <a href="#report" onclick="javascript:report(50482959,2);return false;" title="举报">举报</a></span> </div></div> <style type="text/css"> .embody{ padding:10px 10px 10px; margin:0 -20px; border-bottom:solid 1px #ededed; } .embody_b{ margin:0 ; padding:10px 0; } .embody .embody_t,.embody .embody_c{ display: inline-block; margin-right:10px; } .embody_t{ font-size: 12px; color:#999; } .embody_c{ font-size: 12px; } .embody_c img,.embody_c em{ display: inline-block; vertical-align: middle; } .embody_c img{ width:30px; height:30px; } .embody_c em{ margin: 0 20px 0 10px; color:#333; font-style: normal; }</style><script type="text/javascript"> $(function () { try { var lib = eval("("+$("#lib").attr("value")+")"); var html = ""; if (lib.err == 0) { $.each(lib.data, function (i) { var obj = lib.data[i]; //html += '<img src="' + obj.logo + '"/>' + obj.name + " "; html += ' <a href="' + obj.url + '" target="_blank">'; html += ' <img src="' + obj.logo + '">'; html += ' <em><b>' + obj.name + '</b></em>'; html += ' </a>'; }); if (html != "") { setTimeout(function () { $("#lib").html(html); $("#embody").show(); }, 100); } } } catch (err) { } });</script> <div class="category clearfix"> <div class="category_l"> <img src="http://static.blog.csdn.net/images/category_icon.jpg"> <span>分类:</span> </div> <div class="category_r"> <label onclick="GetCategoryArticles('1271437','wangzhen209','top','50482959');"> <span onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_fenlei']);">network<em>(1)</em></span> <img class="arrow-down" src="http://static.blog.csdn.net/images/arrow_triangle _down.jpg" style="display:inline;"> <img class="arrow-up" src="http://static.blog.csdn.net/images/arrow_triangle_up.jpg" style="display:none;"> <div class="subItem"> <div class="subItem_t"><a href="http://blog.csdn.net/wangzhen209/article/category/1271437" target="_blank">作者同类文章</a><i class="J_close">X</i></div> <ul class="subItem_l" id="top_1271437"> </ul> </div> </label> </div></div>
目录(?)[+]
- TCP Socket
- UDP Socket
Linux下的Socket编程大体上包括Tcp Socket、Udp Socket即Raw Socket这三种,其中TCP和UDP方式的Socket编程用于编写应用层的socket程序,是我们用得比较多的,而Raw Socket则用得相对较少,不在本文介绍范围之列。
TCP Socket
基于TCP协议的客户端/服务器程序的一般流程一般如下:
它基本上可以分为三个部分:
一、建立连接:
- 服务器调用socket()、bind()、listen()完成初始化后,调用accept()阻塞等待,处于监听端口的状态
- 客户端调用socket()初始化后,调用connect()发出SYN段并阻塞等待服务器应答
- 服务器应答一个SYN-ACK段,客户端收到后从connect()返回,同时应答一个ACK段,服务器收到后从accept()返回。
二、传输数据:
建立连接后,TCP协议提供全双工的通信管道,服务器端和客户端根据协议可以通过read和write的反复调用实现数据的传输
三、关闭连接:
当数据传输已经完成后,服务器和客户端可以调用Close关闭连接,一端关闭连接后,另一端read函数则会返回0,可以根据这个特征来感应另一端的退出。
下面就以一个简单的EchoServer演示一下如何创建服务器端和客户端代码,其中和socket相关api都会高亮显示。
服务器端示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define MAXLINE 80
#define SERV_PORT 8000
int main(void)
{
char buf[MAXLINE];
int listenfd = 0;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
sockaddr_in servaddr = {0};
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
bind(listenfd, (sockaddr *)&servaddr, sizeof(servaddr));
listen(listenfd, 20);
printf(”Accepting connections …\n”);
while (1)
{
sockaddr_in cliaddr = {0};
socklen_t cliaddr_len = sizeof(cliaddr);
int connfd = accept(listenfd, (sockaddr *)&cliaddr, &cliaddr_len);
char str[INET_ADDRSTRLEN];
printf(”connected from %s at PORT %d\n”,
inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)),
ntohs(cliaddr.sin_port));
while(true)
{
int count = read(connfd, buf, MAXLINE);
if (count == 0)
break;
write(connfd, buf, count);
}
close(connfd);
printf(”closed from %s at PORT %d\n”,
inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)),
ntohs(cliaddr.sin_port));
}
}
PS:这里需要注意的一下的是sock函数的第二个参数SOCK_STREAM,它表示是一个TCP连接,后面我们会介绍通过传入SOCK_DGRAM打开udp连接。
服务器端主体流程就是一个死循环,它接受一个socket连接,然后将其原封不动的返回给客户端,待客户端退出后,关闭socket连接,再次接受下一个socket连接。
客户端代码如下:
#include <stdio.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define MAXLINE 80
#define SERV_PORT 8000
#define MESSAGE ”hello world”
int main(int argc, char *argv[])
{
char buf[MAXLINE];
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
sockaddr_in servaddr = {0};
servaddr.sin_family = AF_INET;
inet_pton(AF_INET, ”127.0.0.1”, &servaddr.sin_addr);
servaddr.sin_port = htons(SERV_PORT);
if (0 != connect(sockfd, (sockaddr *)&servaddr, sizeof(servaddr)))
{
printf(”connected failed”);
return 1;
}
write(sockfd, MESSAGE, sizeof(MESSAGE));
int count = read(sockfd, buf, MAXLINE);
printf(”Response from server: %s\n”,buf);
close(sockfd);
return 0;
}
客户端代码比较简单,这里就不多介绍了。
UDP Socket
典型的UDP客户端/服务器通讯过程如下图所示:
由于UDP不需要维护连接,程序逻辑简单了很多,但是UDP协议是不可靠的,实际上有很多保证通讯可靠性的机制需要在应用层实现,可能反而会需要更多代码。
典型的示例如下:
/* server.cpp */
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define MAXLINE 80
#define SERV_PORT 8000
int main(void)
{
char buf[MAXLINE];
char str[INET_ADDRSTRLEN];
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
sockaddr_in servaddr = {0};
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
bind(sockfd, (sockaddr *)&servaddr, sizeof(servaddr));
printf(”Accepting connections …\n”);
while (1)
{
sockaddr_in cliaddr;
socklen_t cliaddr_len = sizeof(cliaddr);
int count = recvfrom(sockfd, buf, MAXLINE, 0, (sockaddr *)&cliaddr, &cliaddr_len);
if (count < 0)
{
printf(”recvfrom error”);
continue;
}
printf(”received from %s at PORT %d\n”,
inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)),
ntohs(cliaddr.sin_port));
sendto(sockfd, buf, count, 0, (sockaddr *)&cliaddr, sizeof(cliaddr));
}
}
/* client.cpp */
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define MAXLINE 80
#define SERV_PORT 8000
int main(int argc, char *argv[])
{
char buf[MAXLINE];
char str[INET_ADDRSTRLEN];
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
sockaddr_in servaddr = {0};
servaddr.sin_family = AF_INET;
inet_pton(AF_INET, ”127.0.0.1”, &servaddr.sin_addr);
servaddr.sin_port = htons(SERV_PORT);
while (fgets(buf, MAXLINE, stdin) != NULL)
{
int count = sendto(sockfd, buf, strlen(buf), 0, (sockaddr *)&servaddr, sizeof(servaddr));
if (count == -1)
{
printf(”sendto error”);
return 0;
}
count = recvfrom(sockfd, buf, MAXLINE, 0, NULL, 0);
if (count == -1)
{
printf(”recvfrom error”);
return 0;
}
write(STDOUT_FILENO, buf, count);
}
close(sockfd);
return 0;
}
<div id="digg" articleid="50482959"> <dl id="btnDigg" class="digg digg_disable" onclick="btndigga();"> <dt>顶</dt> <dd>0</dd> </dl> <dl id="btnBury" class="digg digg_disable" onclick="btnburya();"> <dt>踩</dt> <dd>0</dd> </dl> </div> <div class="tracking-ad" data-mod="popu_222"><a href="javascript:void(0);" target="_blank"> </a> </div><div class="tracking-ad" data-mod="popu_223"> <a href="javascript:void(0);" target="_blank"> </a></div><script type="text/javascript"> function btndigga() { $(".tracking-ad[data-mod='popu_222'] a").click(); } function btnburya() { $(".tracking-ad[data-mod='popu_223'] a").click(); } </script>
- socket编程(TCP&UDP)
- socket编程(TCP、UDP)
- socket编程(TCP、UDP)
- Socket编程(TCP、UDP)
- TCP、UDP、SOCKET编程
- Socket编程UDP/TCP
- Socket编程--TCP/UDP
- Socket编程TCP/UDP
- Linux socket编程(TCP,UDP,RAW)
- android 之 socket编程(TCP&UDP)
- Linux socket编程(TCP,UDP,RAW)
- python socket(tcp/udp)编程
- Socket编程(异步通讯)(Tcp,Udp)
- socket与TCP/UDP编程~
- socket与TCP/UDP编程~
- socket与TCP/UDP编程~
- socket与TCP/UDP编程
- socket与TCP/UDP编程
- java.lang.IllegalArgumentException: Result Maps collection already contains value for
- IOS OC中使用Charts的半圆饼图 + 旋转指针
- 函数的声明、定义和调用
- Spring 技术内幕
- 创业大学|什么样的BP能让投资人一见钟情
- socket编程(TCP、UDP)
- PHP通过phpmailer批量发送邮件功能
- Invocation of init method failed;... Result Maps collection already contains value for
- 解决Spring Cloud中Feign/Ribbon第一次请求失败的方法___http://www.jb51.net/article/106944.htm
- Datastage error log 11.3 version
- jsonp+session实现单点登录
- Python机器学习笔记——强化学习
- js parseInt和map函数
- RuntimeError: Unable to create a new session key. It is likely that the cache is unavailable.