您的位置:首页 > 运维架构 > Linux

linux下socket编程归纳记录

2015-06-03 11:20 585 查看
所需头文件:

#include<sys/types.h>
#include<sys/socket.h>


基础套接字:

返回值:
0表示成功
-1表示失败
errno记录错误代码
1:创建套接字
int socket(int domain, int type, int protocol)
参数描述:
domain:套接字域名
{
AF_UNIX:用于本地通信
AF_INET:IPv4,Internet协议(本例使用该域名做参考)
AF_INET6:IPv6,Internet协议
.
.
}
type:套接字类型
{
SOCK_STREAM:流式套接字,用于套接字之间流式I/O操作,需先建立连接。特点1是数据按照写入时顺序被读取方接收,保证传输正确性,因此提供可靠的数据传输;特点2是仅仅是简单将数据交给接收方。
SOCK_DGRAM:数据报套接字,用与无连接通信。数据传输并不严格,接收端不能知道是否丢失了数据。
}
protocaol:使用的协议
{
一般情况下为0,系统会自动选择适合的协议类型。
}
2:请求连接函数:

int connect(int sockfd, const struct sockaddr *servaddr,socklen_t addrlen)
参数描述:
sockfd:sokect生成的套接字
servaddr:客户端准备连接的服务器地址
addrlen:服务器地址的长度

3:绑定本地地址函数:
int bind(int sockfd,const struct sockaddr *myaddr,socklen_t addrlen)
参数描述:
sockfd:sokect生成的套接字
myaddr:分配给套接字sockfd的地址指针
addrlen:myaddr地址的长度
4:监听函数:
int listen(int sockfd,int backlog)
参数描述:
sockfd:sokect生成的套接字
backlog:指完成TCP三次握手后已成功建立的TCP连接的队列长度,服务器执行accept操作从该队列中取下一个连接进行后续处理。
![backlog队列管理](http://img.blog.csdn.net/20150603105753422)
接收请求函数:
int accept(int sockfd, struct sockaddr *cliaddr,socklen_t *addrlen)
参数描述:
sockfd:sokect生成的套接字
cliaddr:用于接收客户端套接字地址的地址结构指针
addrlen:用于接收的套接字地址换岑最大长度的指针
返回值:
如果调用成功,将是一个新的套接字描述符,称为连接套接字,服务器使用该套接字和已建立连接的客户端进行通信,而原有的监听套接字继续接收后续新客户端发来的连接请求。连接套接字在通信完毕后通常会被立刻关闭,但是监听套接字一直处于监听状态直达应用结束。


例子

客户端:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main(void)
{

int st = socket(AF_INET, SOCK_STREAM, 0);//初始化socket,

struct sockaddr_in addr;//定义一个IP地址的结构
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;//设置结构地址类型为TCP/IP地址
addr.sin_port = htons(8080);//指定一个端口号:8080,htons:将short类型从host字节类型到net字节类型转化
addr.sin_addr.s_addr = inet_addr("192.168.182.128");//将字符串类型的IP地址转化为int,赋给addr结构成员.

//调用connect连接到结构addr指定的IP地址和端口号
if (connect(st, (struct sockaddr *) &addr, sizeof(addr)) == -1)
{
printf("connect failed %s\n", strerror(errno));
return EXIT_FAILURE;
}

char s[1024];
memset(s, 0, sizeof(1024));
strcpy(s, "hello world");
if (send(st, s, strlen(s), 0) == -1)//发送buf的数据
{
printf("send failed %s\n", strerror(errno));
return EXIT_FAILURE;
}

close(st);//关闭socket
return EXIT_SUCCESS;

}


服务器端:

#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main(int arg, char *args[])
{
int st = socket(AF_INET, SOCK_STREAM, 0);//初始化socket

int on = 1;
if (setsockopt(st, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1)
{
printf("setsockopt failed %s\n", strerror(errno));
return EXIT_FAILURE;
}

struct sockaddr_in addr;//定义一个IP地址结构
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;//将addr结构的属性定位为TCP/IP地址
addr.sin_port = htons(8080);//将本地字节顺序转化为网络字节顺序。
addr.sin_addr.s_addr = htonl(INADDR_ANY);//INADDR_ANY代表这个server上所有的地址

//将IP与server程序绑定
if (bind(st, (struct sockaddr *) &addr, sizeof(addr)) == -1)
{
printf("bind failed %s\n", strerror(errno));
return EXIT_FAILURE;
}

//server端开始listen,
if (listen(st, 20) == -1)
{
printf("listen failed %s\n", strerror(errno));
return EXIT_FAILURE;
}
char s[1024];
int client_st = 0;//client端socket
//socklen_t len = 0;
struct sockaddr_in client_addr;//表示client端的IP地址
//void *p = &client_addr;
int i;
for (i = 0; i < 5; i++)
{
memset(&client_addr, 0, sizeof(client_addr));
socklen_t len = sizeof(client_addr);
//accept会阻塞,直到有客户端连接过来,accept返回client的socket描述符
client_st = accept(st, (struct sockaddr *)&client_addr , &len);
if (client_st == -1)
{
printf("accept failed %s\n", strerror(errno));
return EXIT_FAILURE;
}
while(1)
{
memset(s, 0, sizeof(1024));
int rc = recv(client_st, s, sizeof(s), 0);//recv是阻塞调用,
if (rc > 0)//接收来自client的消息
{
printf("revc is %s\n", s);
}else
{
if (rc == 0)
{
printf("client socket closed\n");
}else
printf("recv failed %s\n", strerror(errno));
break;
}
}
close(client_st);//关闭client端socket
}
close(st);//关闭server端listen的socket
return EXIT_SUCCESS;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  socket编程