基本的socket编程的介绍

网络IPC:套接字

用socket实现两个不同的主机之间的通信(涉及到一些基本的计算机网络知识  略过。。)

服务器端:

1.socket函数:生成一个套接字

int socket(int domain,int type,int protocol);

参数解析:domain:{AF_INET:Ipv4网络协议,AF_INET6:Ipv6网络协议}

    type:{tcp:SOCK_STREAM,udp:SOCK_DGRAM}

protocol:指定socket所使用的传输协议编号,,一般为0;

2.bind函数

将套接字与地址关联

int bind(int sockfd,const struct sockaddr *addr,socklen_t len);

sockfd:套接字      *addr:地址结构的地址    len:地址结构的长度

IPV4中,套接字地址用结构sockaddr_in表示:

struct sockaddr_in {

sa_family_t sin_family;  //通信域,一般为AF_INET

in_port_t sin_port;       //接口地址,二进制

struct in_addr sin_addr; //iP地址,二进制

}

3.listen函数:使服务器ip和这个端口处于监听状态,如果网络中某一客户机有连接请求,则接受请求。

int listen(int sockfd,int backlog);

sockfd:套接字   backlog:服务器能接受的最大请求,一般为10,最大为128

4.accpet函数:接受客户端的请求,建立与客户机端的通信连接。当服务器处于监听状态时,客户端有连接请求,服务器不会马上处理,而是把这一个请求添加到等待队列中去,等到服务器空闲时再处理。处理时会生成一个新的套接字,这个套接字用于服务器和该客户端进行通信。原来的那个socket套接字继续用于监听。

int accept(int s,struct sockaddr *addr,int *addrlen)

s:socket返回值   addr:结构体指针变量,和bind是同种类型(系统会把远程客户机的IP和端口号放到这个指针变量中去)   addrlen:结构体长度

成功的话返回的值是新的socket套接字

5.recv函数:用新的套接字来接受远程客户端所传来的数据,并且将数据存储到参数buf中去

原型:int recv(int sockfd,void *buf,int len,unsigned int flags);

参数:sockfdà为前面accept的返回值.即new_fd,也就是新的套接字。

  bufà表示缓冲区

  lenà表示缓冲区的长度

  flagsà通常为0

成功会返回接受数据的长度。

6.send函数:用新的套接字发送数据给远程客户端

原型:int send(int s,const void * msg,int len,unsigned int flags);

参数:s为前面accept的返回值.即new_fd

  msg一般为常量字符串

  len表示长度

  flags通常为0

客户端:

1. connect函数:用来请求连接远程服务器,将参数sockfd 的socket 连至参数serv_addr 指定的服务器IP和端口号上去。

原型:int connect (int sockfd,struct sockaddr * serv_addr,int addrlen);

参数:sockfd为前面socket的返回值,即sfd

  serv_addr为结构体指针变量,存储着远程服务器的IP与端口号信息。

  addrlen表示结构体变量的长度

返回值:成功则返回0,失败返回-1

2.close函数:当使用完文件后若已不再需要则可使用close()关闭该文件,并且close()会让数据写回磁盘,并释放该文件所占用的资源

原型:int close(int fd);

参数:fd为前面的sfd,new_fd

返回值:若文件顺利关闭则返回0,发生错误时返回-1

sample:一个简单的通信过程。ps:该程序没有用recv函数和send函数,而是用了read和write函数

服务器端:

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<string.h>
 4 #include<sys/types.h>
 5 #include<arpa/inet.h>
 6 #include<sys/socket.h>
 7 #include<netinet/in.h>
 8 int main(int argc,char *argv[])
 9 {
10     int fd_listen;
11     fd_listen=socket(AF_INET,SOCK_STREAM,0);//套接字
12 
13     if(fd_listen==-1)
14     {
15         perror("socket");
16         exit(1);
17     }
18 struct sockaddr_in seraddr;  //地址结构体
19  memset(&seraddr,0,sizeof(seraddr));
20  seraddr.sin_family=AF_INET;  
21  seraddr.sin_port=htons(1234);//端口
22  seraddr.sin_addr.s_addr=inet_addr("192.168.1.182");//ip地址
23  if(-1==bind(fd_listen,(const struct sockaddr*)&seraddr,(socklen_t)sizeof(seraddr)))
24  {
25    perror("bind");
26    close(fd_listen);
27    exit(1);
28  }
29  listen(fd_listen,10); //监听函数
30 
31  struct sockaddr_in peeraddr;
32  memset(&peeraddr,0,sizeof(peeraddr));
33  socklen_t len=sizeof(peeraddr);
34  int fd_peer=accept(fd_listen,(struct sockaddr*)&peeraddr,&len);
35 
36  printf("who:%s:%d
",inet_ntoa(peeraddr.sin_addr),ntohs(peeraddr.sin_port));
37  if(fd_peer==-1)
38  {
39      perror("accept");
40      close(fd_listen);
41      exit(1);
42  }
43 char buf[1024]="";
44 int readn=read(fd_peer,buf,1023);//从新套接字中读取数据
45 printf("readn:%d,msg:%s
",readn,buf);
46 char *p="-------------------";
47 write(fd_peer,p,strlen(p));
48 close(fd_listen);
49 close(fd_peer);
50 return 0;
51 }
View Code

客户端:

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<string.h>
 4 #include<sys/types.h>
 5 #include<sys/socket.h>
 6 #include<arpa/inet.h>
 7 #include<netinet/in.h>
 8 int main(int argc,char *argv[])
 9 {
10     int sfd=socket(AF_INET,SOCK_STREAM,0);
11     if(sfd==-1)
12     {
13         perror("socket");
14         exit(1);
15     }
16     struct sockaddr_in peeraddr;
17     peeraddr.sin_family=AF_INET;
18     peeraddr.sin_port=htons(1234);
19     peeraddr.sin_addr.s_addr=inet_addr("192.168.1.182");
20 
21     if(-1==connect(sfd,(struct sockaddr*)&peeraddr,sizeof(peeraddr)))//请求连接,把自己的信息添加到套接字中去
22     {
23         perror("connect");
24         close(sfd);
25     }
26     char *p="hello world";
27     write(sfd,p,strlen(p));
28     char buf[1024]="";
29     int readn=read(sfd,buf,1023);
30     printf("readn:%d: %s
",readn,buf);
31     close(sfd);
32     return 0;
33 }
View Code

总结:本程序模拟TCP协议实现了服务器端和客户机端的简单通信,介绍了整个过程。

原文地址:https://www.cnblogs.com/zhaoheng/p/4415691.html