您的位置:首页 > 理论基础 > 计算机网络

Linux C网络编程之Socket套接字

2010-12-04 21:13 369 查看

套接字类型分为3种:流式套接字(SOCK_STREAM),数据包套接字(SOCK_DGRAM)和原始套接字。


流式套接字:提供可靠的,面向连接的通信流,并且,用流式套接字发送的数据顺序是1, 2, 3 ……的话,接收端接收到的数据也是 1, 2, 3……。

 
简言之:TCP连接方式
 

数据包协议:无连接的, 数据独立,无序且不保证数据传输的可靠性。

 
简言之:UDP连接方式
 

流式套接字服务端工作流程:

socket()创建套接字--->bind()套接字名字--->listen()创建套接字队列--->accept()接收连接--->read()读取客户端信息--->write()回复客户端信息--->close()关闭客户端socket连接
 

socket(int domain, int type, int protocol)

 
domain:地址族

domain的取值范围如下表,大多数情况下会使用AF_UNIX  /  AF_INET:
 
 
参数说明
AF_UNIXUNIX内部(文件系统套接字)
AF_INETARPA因特网协议(UNIX网络套接字)
AF_ISOISO标准协议
AF_NS
AF_IPXNOVELL IPX协议
AF_APPLETALKAppletalk DDS
 
type:套接字对应的通信类型(SOCK_STREAM   /   SOCK_DGRAM)

protocol:协议,参数默认值0,根据套接字类型和域决定。如SOCK_STREAM 对应 0。
 
 

套接字地址:

这里介绍AF_UNIX和AF_INET的套接字地址

AF_UNIX是包含在sys/un.h头文件中的sockaddr_un结构,该结构定义为:
 
struct sockaddr_un {

       sa_family_t sun_family;     //是一个short类型

  
       char sun_path[];    //路径长度有限:不能超过108个字符

}

 
AF_INET是包含在netinet/in.h中的sockaddr_in结构,该结构为:
 
struct sockaddr_in {

        short int sin_family;     //AF_INET

        unsigned short int sin_port;  //端口号

        struct in_addr sin_addr;    //Internet地址

}
 

套接字的名字(bind())

int bind(int socket, const struct sockaddr *address, size_t address_len);

成功返回0,否则返回-1,并有errno变量
 


创建套接字队列  listen()

int listen(int socket, int backlog);
 
backlog设置连接的个数,套接字上排列的接入连接个数最多不能超过这个数字。常用值为5.

成功返回0,否则返回-1.
 
 

接收连接 accept()

 
int accept( int socket, struct sockaddr *address, size_t   *address_len);
 

请求连接 connect()

 
int connect(int socket, const struct sockaddr *address, size_t address_len);
 

read():读取数据


write():写入/返回数据

 

关闭连接 close(socket 标识符)


服务器端代码:

#include <sys/types.h>#include <sys/socket.h>#include <stdio.h>#include <netinet/in.h>#include <arpa/inet.h>#include <unistd.h>int main(void){int server_sockfd, client_sockfd;    //保存服务器和客户端的套接字标识符int server_len, client_len;          //保存服务器和客户消息长度struct sockaddr_in server_address;   //定义服务器套接字地址struct sockaddr_in client_address;   //定义客户套接字地址server_sockfd = socket(AF_INET, SOCK_STREAM, 0);  //定义套接字类型server_address.sin_family = AF_INET; //定义套接字地址中的域server_address.sin_addr.s_addr = inet_addr("127.0.0.1"); //定义套接字地址server_address.sin_port = 9734;      //定义套接字端口server_len = sizeof(server_address);bind(server_sockfd, (struct sockaddr *) &server_address, server_len);//定义套接字名字listen(server_sockfd, 5);  //创建套接字队列while(1){char ch;printf("服务器等待消息/n");client_len = sizeof(client_address);client_sockfd = accept(server_sockfd,     //接收连接(struct sockaddr *) &client_address,(socklen_t *__restrict) &client_len);read(client_sockfd, &ch, 1);   //读取客户消息ch++;write(client_sockfd, &ch, 1);  //向客户传送消息close(client_sockfd);          //关闭连接}return 0;}

 

客户端代码:

#include <sys/types.h>#include <sys/socket.h>#include <stdio.h>#include <netinet/in.h>#include <arpa/inet.h>#include <unistd.h>int main(void){int sockfd;int len;struct sockaddr_in address;int result;char ch = 'a';sockfd = socket(AF_INET, SOCK_STREAM, 0);address.sin_family = AF_INET;address.sin_addr.s_addr = inet_addr("127.0.0.1");address.sin_port = 9734;len = sizeof(address);result = connect(sockfd, (struct sockaddr *) &address, len);if(result == -1){perror("连接失败");return 1;}write(sockfd, &ch, 1);read(sockfd, &ch, 1);printf("服务器的消息是%c/n", ch);close(sockfd);return 0;}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息