LINUX程序设计-socket程序设计

什么是套接字:

套接字是一种通信过程,它使客户/服务器系统的开发工作既可以在本地单机上进行,也可以跨网络进行。 

套接字建立过程:

1,创建一个套接字,这是分配给该服务器进程的一个操作系统资源,套接字由服务器通过系统调用socket创建出来的,所以其它进程将不能对它进行访问。

2,给套接字起个名字,用系统调用bind,然后服务器就开始等待有客户连接到这个命名套接字上来。系统调用listen创建一个队列,来自客户的连接将在这个队列上排队等待服务器的处理,服务器将通过系统调用accept来接受来自客户的接入连接。

3,当服务器调用accept的时候,会新创建一个套接字,新套接字的唯一用途就是与这个特定的客户进行通信,而命名套接字则被解放出来,准备处理来自其它客户的连接。

客户端:
先通过调用socket创建一个未命名的套接字,然后调用connect利用服务器的命名套接
字和一个地址来建立一个连接。
套接字建立后,可以像操作底层文件描叙符一样用它来实现数据通信。

一个简单的服务器端:
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <sys/un.h>
#include <unistd.h>

int main()
{
 int server_sockfd,client_sockfd;
 int server_len,client_len;
 struct sockadd_un server_address;
 struct sockadd_un client_address;

/删除以前的套接字,再为服务器创建一个未命名套接字
 unlink("server_socket");
 server_sockfd = socket(AF_UNIX, SOCK_STREAM, 0);

/         给套接字起名字                //
 server_address.sun_family = AF_UNIX;
 stycpy(server_address.sun_path, "server_socket");
 server_len = sizeof(server_address);
 bind(server_sockfd,(struct sockaddr *)&server_address,server_len);

/创建一个连接队列,开始等待客户的到来
 listen(server_sockfd, 5);
 while(1){
 char ch;

 printf("server waiting/n");

/接受一个连接 /
 client_len = sizeof(client_address);
 client_sockfd = accept(server_sockfd,(struct sockadd *)
&client_address, &client_len);

//对client_sockfd套接字上的客户进行读写///
 read(client_sockfd,&ch,1);
 ch++;
 write(client_sockfd,&ch,1);
 close(client_sockfd);
 }
}


一个简单的客户端:
#include <stdio.h>
#include <sys/types.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <unistd.h>

int main()
{
int sockfd;
int len;
struct sockaddr_un address;
int result;
char ch = 'a';

//为客户创建一个套接字/
sockfd = socket (AF_UNIX, SOCK_STREAM, 0);

//根据服务器设置的情况给这个套接字起个名字/
address.sun_family = AF_UNIX;
stycpy (address.sun_path, "server_socket");
len = sizeof(address);

///把套接字连接到服务器的套接字///
result = connect (sockfd, (struct sockaddr *)&address,len);

if(result == -1)
{perror("oops:client1");
exit(1);
}

///读写操作///
write(sockfd,&ch,1);
read(sockfd,&ch,1);
printf("char from server = %c/n",ch);
close(sockfd);
exit(0);
}

详细说明:
创建一个套接字:
#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain,int type ,int protocol);

创建出来的套接字是一条通信线路的一个端点。domain参数负责指定地址族,type参数负责指定与这个套接字一起使用的通信类型,而Portocol参数负责指定所使用的协议。

domain:参数可以使用的域如表:
AF_UNIX: UNXI内部(文件系统套接字)
AF_INET: APRA因特网协议(UNIX网络套接字)
AF_ISO:  ISO标准协议
AF_NS:  施乐网络系统协议
AF_IPX:  novell IPX协议
AF_APPLETALK: Appletalk DDS

type:指定了与新套接字对应的通信特性。它的取值包括SOCK_STREAM和SOCK_DGRAM。
SOCK_STREAM是一个有序的,可靠的,基于连接的双向字节流。TCP协议
SOCK_DGRAM是一个数据图服务。无保证的连接,对于AF_INET域使用UDP协议

protocol:通信所用的协议通常是由套接字的类型和套接字的域来决定的,一般不再有可挑选的余地,如果还能挑选,就需要用到protocol参数,0选择缺省的协议。

socket系统调用返回的是一个描叙符,它在许多方面类似于一个底层的文件描叙符。

套接字地址:
每个套接字域都有它自己的地址格式,
AF_UNIX套接字的地址是一个定义在sys/un.h头文件里的sockaddr_un结构:
struct sockaddr_un{
sun_family_t     sun_family;
char                  sun_path[ ];
};
AF_INET套接字的地址是一个定义在netinet/in.h头文件里的sockaddr_in结构确定的。
struct sockaddr_in{
short int                    sin_family;
unsigned shor int     sin_port;
struct in_addr           sin_addr;
};
IP地址结构in_addr被定义为:
struct in_addr{
unsigned long int   s_addr;
};

给套接字起名字:
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *address,size_t address_len);
作用:把参数address中给出的地址赋值给与文件描叙符socket相关联的未命名的套接字。地址结构的长度是通过address_len参数传递的。

创建套接字队列:
#include <sys/socket.h>
int listen(int socket,int backlog);

backlog为最大队列长度,常用的值是5;

接受连接:
#include <sys/socket.h>
int accept(int socket,struct sockaddr * address,size_t *address_len);

accept调用会等到有客户程序试图连接到由socket参数指定的套接字时才返回。该客户就是排在队列第一位的连接。accept函数将创建出一个新的套接字来与客户进行通信,返回的是与之对应的文件描叙符。新套接字的类型与服务器监听套接字的类型是一样的。

请求连连:
#include <sys/socket.h>
int connect(int socket,const sockaddr *address,size_t address_len);
参数socket指定的套接字将连接到参数address指定的服务器套接字上去。

关闭套接字int close ( int socket);

 


select调用:
#include <sys/types.h>
#include <sys/time.h>
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds,struct timeval *timeout);

select调用的作用是检查那个文件描叙符集合里是否有一个文件描叙符处于读操作就绪状态,写操作就绪或有个错误排队的状态,如果没有,就阻塞到这些状态有一个出现为止。

nfds参数给出了需要进行测试的文件描叙符个数,测试将对第0到第(nfds-1)个描述符进行。三个描述符集合都可以是一个空指针,这表示不进行相应的测试。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值