BSD Socket 简单涉猎 (一)
2014-05-07 16:40
295 查看
写在前面
未完!参考博客文章
http://www.linuxeden.com/html/unix/20001213/18630.html
http://www.oschina.net/code/snippet_97047_675
http://blog.csdn.net/shisqf/article/details/6563942
主要参考:
/article/4954424.html
代码也是来自这篇博文,我对socket编程理解也不强,有错误欢迎大家指出讨论
直接进入正题
测试在mac OS X 中代码也运行 代码是一个一对一的聊天例子,收一条发一条
效果如图:
我是图片。我还没别添加。
在终端中
gcc -o server server.c
./server
gcc -o client client.c
./client
解释代码,完整代码会在后面贴出
struct sockaddr_in server_addr;
sockaddr_in是一个结构体(在netinet/in.h中定义)(这一段转自百度百科http://baike.baidu.com/view/2355183.htm?fr=aladdin):
structsockaddr_in{ shortsin_family;/*Addressfamily一般来说AF_INET(地址族)PF_INET(协议族)*/ unsignedshortsin_port;/*Portnumber(必须要采用网络数据格式,普通数字可以用htons()函数转换成网络数据格式的数字)*/ structin_addrsin_addr;/*Internetaddress*/ unsignedcharsin_zero[8];/*Samesizeasstructsockaddr没有实际意义,只是为了 跟SOCKADDR结构在内存中对齐*/ };但是在 BSD中 sockaddr_in是这样的
(不同的系统略有不同?)
/* * Socket address, internet style. */ struct sockaddr_in { __uint8_t sin_len; sa_family_t sin_family;//通信类型 in_port_t sin_port;//端口 struct in_addr sin_addr;//地址 char sin_zero[8]; };
关于sin_family 有兴趣可以看我转载的点击打开链接/article/8870521.html
一般写AF_INET 就可以了 代表TCP/IP协议
server_addr.sin_len = sizeof(struct sockaddr_in);
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(11332);//通信端口
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
socket(int domain, int type, int protocol)
在参数表中,domain指定使用何种的地址类型,比较常用的有:PF_INET, AF_INET: Ipv4网络协议;
PF_INET6, AF_INET6: Ipv6网络协议。
一般我们用AF_INET
type参数的作用是设置通信的协议类型,可能的取值如下所示:
SOCK_STREAM: 提供面向连接的稳定数据传输,即TCP协议。
一般用SOCK_STREAM
其他了解就可以了
OOB: 在所有数据传送前必须使用connect()来建立连接状态。
SOCK_DGRAM: 使用不连续不可靠的数据包连接。
SOCK_SEQPACKET: 提供连续可靠的数据包连接。
SOCK_RAW: 提供原始网络协议存取。
SOCK_RDM: 提供可靠的数据包连接。
SOCK_PACKET: 与网络驱动程序直接通信。
参数protocol用来指定socket所使用的传输协议编号。一般为0。
socket(AF_INET, SOCK_STREAM, 0)能能理解了把 ,成功返回0 失败返回-1 当-1的时候,提示错误
server端代码
#include <stdio.h> #include <netinet/in.h> #include <sys/socket.h> #include <arpa/inet.h> #include <string.h> int main (int argc, const char * argv[]) { struct sockaddr_in server_addr; server_addr.sin_len = sizeof(struct sockaddr_in); server_addr.sin_family = AF_INET;//Address families AF_INET互联网地址簇 server_addr.sin_port = htons(11332); server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); bzero(&(server_addr.sin_zero),8); //创建socket int server_socket = socket(AF_INET, SOCK_STREAM, 0);//SOCK_STREAM 有连接 if (server_socket == -1) { perror("socket error"); return 1; } //绑定socket:将创建的socket绑定到本地的IP地址和端口,此socket是半相关的,只是负责侦听客户端的连接请求,并不能用于和客户端通信 int bind_result = bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)); if (bind_result == -1) { perror("bind error"); return 1; } //listen侦听 第一个参数是套接字,第二个参数为等待接受的连接的队列的大小,在connect请求过来的时候,完成三次握手后先将连接放到这个队列中,直到被accept处理。如果这个队列满了,且有新的连接的时候,对方可能会收到出错信息。 if (listen(server_socket, 5) == -1) { perror("listen error"); return 1; } struct sockaddr_in client_address; socklen_t address_len; int client_socket = accept(server_socket, (struct sockaddr *)&client_address, &address_len); //返回的client_socket为一个全相关的socket,其中包含client的地址和端口信息,通过client_socket可以和客户端进行通信。 if (client_socket == -1) { perror("accept error"); return -1; } char recv_msg[1024]; char reply_msg[1024]; while (1) { bzero(recv_msg, 1024); bzero(reply_msg, 1024); printf("reply:"); scanf("%s",reply_msg); send(client_socket, reply_msg, 1024, 0); long byte_num = recv(client_socket,recv_msg,1024,0); recv_msg[byte_num] = '\0'; printf("client said:%s\n",recv_msg); } return 0; }
client端代码:
#include <stdio.h> #include <netinet/in.h> #include <sys/socket.h> #include <arpa/inet.h> #include <string.h> int main (int argc, const char * argv[]) { struct sockaddr_in server_addr; server_addr.sin_len = sizeof(struct sockaddr_in); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(11332); server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); bzero(&(server_addr.sin_zero),8); int server_socket = socket(AF_INET, SOCK_STREAM, 0); if (server_socket == -1) { perror("socket error"); return 1; } char recv_msg[1024]; char reply_msg[1024]; if (connect(server_socket, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_in))==0) { //connect 成功之后,其实系统将你创建的socket绑定到一个系统分配的端口上,且其为全相关,包含服务器端的信息,可以用来和服务器端进行通信。 while (1) { bzero(recv_msg, 1024); bzero(reply_msg, 1024); long byte_num = recv(server_socket,recv_msg,1024,0); recv_msg[byte_num] = '\0'; printf("server said:%s\n",recv_msg); printf("reply:"); scanf("%s",reply_msg); if (send(server_socket, reply_msg, 1024, 0) == -1) { perror("send error"); } } } // insert code here... printf("Hello, World!\n"); return 0; }
相关文章推荐
- VC维
- ethtool 在 Linux 中的实现框架和应用
- linux中文件描述符fd和struct file结构体的释放
- CSS3 Transitions, Transforms和Animation使用简介与应用展示
- 9859898
- Merge Sorted Array
- 如何使用reshape包进行数据汇总
- 在 ArcMap 中显示影像和栅格数据快速浏览
- POJ 1775 sum of Factorial (数论)
- 不要被骗,带你看看产品经理的真实状态!
- iOS-屏幕快照(UIView快照,SubView快照)
- Ejabberd优化
- 498989495956
- POJ_3414_BFS pots
- 最好的母亲节礼物
- POJ_3414_BFS pots
- 5346546
- 搜狐克己节目《隐秘而无穷》 称要“名利双收”
- DES安全编码组件
- 涨姿势!优秀网页布局对比(二)