粉丝不过W
socket 基础编程
函数说明
socket: 建立一个 socket 连接,可指定 socket 类型等信息。在建立 socket连接之后,可对 socketadd 或 sockaddr_in 进行初始化,以保存所建立的 socket 信息
bind:把本地 IP 地址绑定端口号的,若绑定其他地址则不能成功。它主要用于 TCP 的连接,而在 UDP 的连接中则无必要
connect: TCP :用于 bind 的之后的 client 端,用于与服务器端建立连接,而 UDP 由于没有 bind 函数,因此用 connect 类似 bind 函数的作用
send 和 recv:用于接收和发送数据,可用到 TCP ,也可用到 UDP中。当用到 UDP 时,可在 connect 函数建立连接之后再用
sendto 和 recvfrom:作用与 send 和 recv 函数类型,也可以用在 TCP 和UDP 中。 TCP 时,后面的几个与地址有关参数不起作用,函数作用等同于 send 和 recv。 UDP 时,可用在没有使用 connect 之前,可 自动寻找制定地址并进行连接
TCP 协议 socket 编程流程图:
UDP 协议 socket 编程流程图
socket
#include <sys/socket.h>
/*
*parameter:
* family:
* AF_INET: IPv4 协议
* AF_INET6:IPv6 协议
* AF_LOCAL:UNIX 域协议
* AF_ROUTE:路由套接字(socket)
* AF_KEY: 密钥套接字(socket)
* type:
* SOCK_STREAM: 字节流套接字 socket
* SOCK_DGRAM: 数据报套接字 socket
* SOCK_RAW: 原始套接字 socket
* protoco:0 (原始套接字除外)
*return:
* 成功:非负套接字描述符
* 失败:-1
*/
int socket(int family, int type, int protocol)
bind
#include <sys/socket.h>
/*
*parameter:
* socktd:套接字描述符
* my_addr:本地地址
* addrlen:地址长度
*return:
* 成功:0
* 出错:-1
*/
int bind(int sockfd, struct sockaddr *my_addr, int addrlen)
listen
#include <sys/socket.h>
/*
*parameter:
* socktd:套接字描述符
* backlog:请求队列中允许的最大请求数,大多数系统缺省值为 20
*return:
* 成功:0
* 出错:-1
*/
int listen(int sockfd,int backlog)
accept
#include <sys/socket.h>
/*
*parameter:
* socktd:套接字描述符
* addr:客户端地址
* addrlen:地址长度
*return:
* 成功:0
* 出错:-1
*/
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
connect
#include <sys/socket.h>
/*
*parameter:
* socktd: 套接字描述符
* serv_addr:服务器端地址
* addrlen: 地址长度
*return:
* 成功:0
* 失败:-1
*/
int connect(int sockfd, struct sockaddr *serv_addr, int addrlen)
send
#include <sys/socket.h>
/*
*parameter:
* socktd:套接字描述符
* msg:指向要发送数据的指针
* len:数据长度
* flags:一般为 0
*return:
* 成功:发送的字节数
* 出错:-1
*/
int send(int sockfd, const void *msg, int len, int flags)
recv
#include <sys/socket.h>
/*
*parameter:
* socktd:套接字描述符
* buf:存放接收数据的缓冲区
* len:数据长度
* flags:一般为 0
*return:
* 成功:接收的字节数
* 出错:-1
*/
int recv(int sockfd,void *buf,int len,unsigned int flags)
sendto
#include <sys/socket.h>
/*
*parameter:
* socktd:套接字描述符
* msg:指向要发送数据的指针
* len:数据长度
* flags:一般为 0
* to:目地机的 IP 地址和端口号信息
* tolen:地址长度
*return:
* 成功:发送的字节数
* 出错:-1
*/
int sendto(int sockfd,
const void *msg,
int len,
unsigned int flags,
const struct sockaddr *to,
int tolen)
recvfrom
#include <sys/socket.h>
/*
*parameter:
* socktd:套接字描述符
* buf:存放接收数据的缓冲区
* len:数据长度
* flags:一般为 0
* from:源机的 IP 地址和端口号信息
* tolen:地址长度
*return:
* 成功:接收的字节数
* 出错:-1
*/
int recvfrom(int sockfd,
void *buf,
int len,
unsigned int flags,
struct sockaddr *from,
int *fromlen)
服务器端
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#define SERVPORT 3333
#define BACKLOG 10
#define MAX_CONNECTED_NO 10
#define MAXDATASIZE 5
int main()
{
struct sockaddr_in server_sockaddr, client_sockaddr;
int sin_size, recvbytes;
int sockfd, client_fd;
char buf[MAXDATASIZE];
/* 建立 socket 连接 */
if((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1)
{
perror("socket");
exit(1);
}
printf("socket success!,sockfd=%d\n",sockfd);
/* 设置 sockaddr_in 结构体中相关参数 */
server_sockaddr.sin_family = AF_INET;
server_sockaddr.sin_port = htons(SERVPORT);
server_sockaddr.sin_addr.s_addr = INADDR_ANY;
/* 绑定函数 bind */
bzero(&(server_sockaddr.sin_zero), 8);
if(bind(sockfd, (struct sockaddr *)&server_sockaddr, sizeof(struct sockaddr)) == -1)
{
perror("bind");
exit(1);
}
printf("bind success!\n");
/*调用 listen 函数*/
if(listen(sockfd,BACKLOG) == -1)
{
perror("listen");
exit(1);
}
printf("listening....\n");
/*调用 accept 函数,等待客户端的连接*/
if((client_fd = accept(sockfd, (struct sockaddr *)&client_sockaddr, &sin_size)) == -1)
{
perror("accept");
exit(1);
}
/*调用 recv 函数接收客户端的请求*/
if((recvbytes = recv(client_fd, buf, MAXDATASIZE, 0)) == -1)
{
perror("recv");
exit(1);
}
printf("received a connection :%s\n",buf);
close(sockfd);
}
客户端
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define SERVPORT 3333
#define MAXDATASIZE 100
int main(int argc, char *argv[])
{
int sockfd, sendbytes;
char buf[MAXDATASIZE];
struct hostent *host;
struct sockaddr_in serv_addr;
if(argc < 2)
{
fprintf(stderr,"Please enter the server's hostname!\n");
exit(1);
}
/* 地址解析函数 */
if((host = gethostbyname(argv[1])) == NULL)
{
perror("gethostbyname");
exit(1);
}
/* 创建 socket */
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket");
exit(1);
}
/* 设置 sockaddr_in 结构体中相关参数 */
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SERVPORT);
serv_addr.sin_addr = *((struct in_addr *)host->h_addr);
bzero(&(serv_addr.sin_zero),8);
/* 调用 connect 函数主动发起对服务器端的连接 */
if(connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr)) == -1)
{
perror("connect");
exit(1);
}
/* 发送消息给服务器端 */
if((sendbytes = send(sockfd, "hello", 5, 0)) == -1)
{
perror("send");
exit(1);
}
close(sockfd);
}