您的位置:首页 > 其它

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: