使用bind来关联地址和套接字

#include <sys/types.h>
#include <sys/socket.h> int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
返回值:成功0,出错-
sockfd:已经建立的socket描述符
addr:指向sockaddr的结构体指针
addrlen:addr结构的长度

getsockname函数来发现绑定到套接字上的地址

#include <sys/socket.h>

int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
返回值:成功0,出错-
sockfd:已经建立的socket描述符
addr:指向sockaddr的结构体指针
addrlen:addr结构的长度

如果套接字已经和对等方连接,可以调用getpeername函数来找到对方的地址

#include <sys/socket.h>

int getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
返回值:成功0,出错-
sockfd:已经建立的socket描述符
addr:指向sockaddr的结构体指针
addrlen:addr结构的长度

使用connect函数来建立连接

#include <sys/types.h>
#include <sys/socket.h> int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
返回值:成功0,出错-
sockfd:已经建立的socket描述符
addr:指向sockaddr的结构体指针
addrlen:addr结构的长度

服务器调用listen函数来宣告它愿意接收连接请求

#include <sys/types.h>
#include <sys/socket.h> int listen(int sockfd, int backlog);
返回值:成功0,出错-
sockfd:已经建立的socket描述符
backlog:等待连接队列的最大长度

使用accept函数获取连接请求并建立连接

#include <sys/types.h>
#include <sys/socket.h> int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
返回值:成功文件(套接字)描述符,出错-
sockfd:已经建立的socket描述符
addr:指向sockaddr的结构体指针
addrlen:addr结构的长度

send和write很像,但是可以指定标志来改变处理传输数据的方式

#include <sys/types.h>
#include <sys/socket.h> ssize_t send(int sockfd, const void *buf, size_t len, int flags);
返回值:成功返回发送字节数,出错-
sockfd:socket描述符
len:缓冲区数据长度
flags:调用执行方式

sendto可以在无连接的套接字上指定一个目标地址

#include <sys/types.h>
#include <sys/socket.h> ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
返回值:成功发送的字节数,出错-
sockfd:socket描述符
buf:带发送数据缓冲区
len:缓冲区长度
flags:调用方式标志位,一般为0
dest_addr:指向目的套接字地址
addrlen:所指地址长度

可以调用带有msghdr结构的sendmsg来指定多重缓冲区传输数据,这和writev函数很相似

#include <sys/types.h>
#include <sys/socket.h> ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
返回值:成功发送的字节数,出错-
sockfd:socket描述符
msg:信息头结构指针
flags:可选标记参数位,和send或是sendto参数相同

msghdr结构

struct msghdr {
void *msg_name; /* optional address */
socklen_t msg_namelen; /* size of address */
struct iovec *msg_iov; /* scatter/gather array */
size_t msg_iovlen; /* # elements in msg_iov */
void *msg_control; /* ancillary data, see below */
size_t msg_controllen; /* ancillary data buffer len */
int msg_flags; /* flags (unused) */
};

struct msghdr

函数recv和read相似,但是recv可以指定标志来控制如何接收数据

#include <sys/types.h>
#include <sys/socket.h> ssize_t recv(int sockfd, void *buf, size_t len, int flags);
返回值:数据字节长度,若无可用数据或对等方已经按序结束返回0,出错-
sockfd:socket描述符
buf:接收数据缓冲
len:buf的长度
flags:可选标记位

如果发送者已经调用shutdown来结束传输,或者网络协议支持按默认的顺序关闭并且发送端已经关闭,那么当所有的数据接收完毕后,recv会返回0

如果兴趣定位发送者,可以使用recvfrom来得到数据发送者的源地址

#include <sys/types.h>
#include <sys/socket.h> ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
返回值:返回数据字节长度,若无可用数据或对等方已经按序结束,返回0,出错-
sockfd:socket描述符
buf:及诶手数据缓冲
len:buf长度
flags:可选标记位
src_addr:如果非空,它将包含数据发送者的套接字端点地址
addrlen:src_addr参数长度

为了将数据送入多个缓冲区,或者想接收辅助数据,可以使用recvmsg

#include <sys/types.h>
#include <sys/socket.h> ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);
返回值:返回数据的自及诶长度,若无可用数据或对等方已经按序结束,返回0,出错-
sockfd:socket描述符
msg:信息头结构指针
flags:可选标志位

可以使用setsockopt函数来设置套接字选项

#include <sys/types.h>
#include <sys/socket.h> int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
返回值:成功0,失败-
sockfd:socket描述符
level:标识了选项应用的协议
optname:需要设置的选项
optval:指向存放选项值的缓冲区指针
optlen:optval的长度

可以使用getsockopt函数来查看选项的当前值

#include <sys/types.h>
#include <sys/socket.h> int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);
返回值:成功0,失败-
sockfd:socket描述符
level:标识了选项应用的协议
optname:需要设置的选项
optval:指向存放选项值的缓冲区指针
optlen:指向optval缓冲区的长度

TCP例程:

服务器端:

 #include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h> #define MAXLINE 80
#define SERV_PORT 8000 int main(void)
{
char buf[MAXLINE];
int listenfd = ; listenfd = socket(AF_INET, SOCK_STREAM, ); struct sockaddr_in servaddr = {};
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY); bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
listen(listenfd, ); printf("Accepting connections ...\n");
while()
{
struct sockaddr_in cliaddr = {};
socklen_t cliaddr_len = sizeof(cliaddr);
int connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len); char str[INET_ADDRSTRLEN];
printf("connect from %s at PORT %d\n",
inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)),
ntohs(cliaddr.sin_port));
while()
{
int count = read(connfd, buf, MAXLINE);
if(count == )
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));
}
}

server.c

客户端:

 #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, ); struct sockaddr_in servaddr = {};
servaddr.sin_family = AF_INET;
inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);
servaddr.sin_port = htons(SERV_PORT); if(connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != )
{
printf("connected failed");
return ;
} write(sockfd, MESSAGE, sizeof(MESSAGE));
int count = read(sockfd, buf, MAXLINE); printf("Response from server: %s\n", buf); close(sockfd);
return ;
}

client.c

linux IPC socket(2)的更多相关文章

  1. Linux IPC socket 广播,组播

    getsockopt()/setsockopt() //获得sockfd指向的socket的属性 int getsockopt(int sockfd, int level, int optname, ...

  2. Linux IPC socket编程基础

    头文件 #include<unistd.h> #include <sys/types.h> #include <sys/socket.h> #include< ...

  3. linux IPC socket(3)server简单写法

    写server的一些流程总结 一.向内核申请一个socket TCP形式 sock_fd = socket(AF_INET, SOCK_STREAM, ); UDP形式 sfd = socket(AF ...

  4. linux IPC socket

    套接字是通讯端点的抽象 创建一个套接字 #include <sys/types.h> #include <sys/socket.h> int socket(int domain ...

  5. Linux IPC实践(1) -- 概述

    进程的同步与互斥 进程同步: 多个进程需要相互配合共同完成一项任务. 进程互斥: 由于各进程要求共享资源,而且有些资源需要互斥使用,因此各进程间竞争使用这些资源,进程的这种关系为进程的互斥;系统中某些 ...

  6. linux系统socket通信编程详解函数

    linux socket编程之TCP与UDP   TCP与UDP区别 TCP---传输控制协议,提供的是面向连接.可靠的字节流服务.当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之 ...

  7. linux ipc/its

    linux进程间双向消息队列 server.c #include <stdio.h> #include <stdlib.h> #include <string.h> ...

  8. linux中socket的理解

    对linux中socket的理解 一.socket 一般来说socket有一个别名也叫做套接字. socket起源于Unix,都可以用“打开open –> 读写write/read –> ...

  9. linux 客户端 Socket 非阻塞connect编程

    开发测试环境:虚拟机CentOS,windows网络调试助手        非阻塞模式有3种用途        1.三次握手同时做其他的处理.connect要花一个往返时间完成,从几毫秒的局域网到几百 ...

随机推荐

  1. 【leetcode】985. Sum of Even Numbers After Queries

    题目如下: We have an array A of integers, and an array queries of queries. For the i-th query val = quer ...

  2. Antd Vue 问题集合

    1.table列宽问题 在滚动列时,如果要指定列宽,不要指定所有列宽,至少预留一列不执行列宽. 同时:scroll="{ x: width}", width的值要是所有列的宽度之和 ...

  3. qt 学习(六) 数据库注册用户

    做什么: 1 登陆按钮按下出现注册页面, 2 输入账号  判断是否可用   查询数据库,用户名是否已经注册 3 输入密码  判断密码格式 4 输入邮箱  判断邮箱格式   查询数据库,邮箱是否已经注册 ...

  4. src/lib/framework/src/driverFramework.cpp学习

    int Framework::initialize() { DF_LOG_DEBUG("Framework::initialize"); g_framework = new Syn ...

  5. UVa 11384 (推公式+递归)

    题目: 给你1到n,现在让你将每个数变成0,每一步操作可以选取任意数一起减去一个整数,减完了不能为负数!问你最少需要几步? 巨水的题,然而为什么要写博客呢?提醒自己要记得递归函数,不要傻傻的开数组硬比 ...

  6. Python基础教程(007)--Python的优缺点

    前言 了解Python的优点和缺点 知识点 优点 简单易学 免费,开源 面相对象 丰富的库 可扩展性 缺点 运行速度慢 国内市场较小 中文资料匮乏 总结: 明白Python的优点和缺点

  7. delphi 动态获取文件类型的图标

    delphi 动态获取文件类型的图标.txt我不奢望什么,只希望你以后的女人一个不如一个.真怀念小时候啊,天热的时候我也可以像男人一样光膀子!在应用程序的编写中,组合框(ComboBox).列表框(L ...

  8. jenkins安装-配置

    jenkins安装-配置 注意: jenkins访问 用chrome浏览器 安装包下载:http://pkg.jenkins-ci.org/redhat/ (使用2.92版本的) 安装jdk: 1.8 ...

  9. 移动 web 端屏幕适配 - rem

    前言 最近整理了一下以前学习前端的笔记,发现自己对移动 web 端屏幕适配(rem)这一块并没有真正理解,只是会用.接下来,把自己的一些对移动 web 端屏幕适配(rem)的思考记录下来. rem 介 ...

  10. 启发式分治:2019牛客多校第三场 G题 Removing Stones

    问题可以转换为求有多少个区间数字的总和除2向下取整大于等于最大值.或者解释为有多少个区间数字的总和大于等于最大值的两倍(但是若区间数字总和为奇数,需要算作减1) 启发式分治: 首先按最大值位置分治,遍 ...