网络编程--tcp

来源:互联网 发布:飞鹰直销软件 编辑:程序博客网 时间:2024/06/05 09:09

网络编程:

1、概念:客户端:接收数据的一端

         服务器:提供数据的一端

2、网络通讯协议的选择:

 Tcp:面向链接可靠的流式服务,当双发持续的发送数据采用面向连接方式

内核维护一条专用传输线路用来通信

Udp:无连接 不可靠的数据报服务

可不可靠看两点:能不能收到数据,数据能不能到

3、编程

Tcp的编程流程

Server:socket  bind  listen (监听有没有链接)、accept  recv/sent  close

Client:socket  bind(可有可无,服务器可自动获取客户端地址) connect  recv/send  close

函数详解:以下函数成功均返回0,失败返回-1

创建套接字

 int sockfd=socket(int  domain,int type,int prototal)

 第一个参数:协议族,通常使用AF_INETPF_INET

第二个参数: 选择什么协议SOCK_STREAM(tcp)SOCK_DGRAM(udp)

套接字绑定ip和端口号

Socket命名:

Int bind(int sockfd,conts struct sockaddr *addr,socklen_t addrlen)

第一个参数套接字id,第二个参数保存ip和端口号的结构体(里面有地址族类型)现在用sockaddr_in

注:在调用bind函数时一般不要将端口号置为小于1024的值,因为1到1024是保留端口号,你可以选择大于1024中的任何一个没有被占用的端口号。

命名失败原因:端口号被占用,ip地址错误

 

监听套接字:

 Int  listen(int sockfd,int backlog);

创建一个监听队列,第二个参数表示创建队列的大小

 

接受连接:

int c=accept(int sockfd,(struct sockaddr*)&cli,&len);这个返回值是文件描述符,指向建立的那条链接

Socket文件描述符只负责链接,而此时的c才是传送数据的

 

发起连接:

Int connect(int sockfd,struct sockaddr* addr,int* addrlen);

第一个参数是系统为客户端自动分配的socket,第二个参数为服务器监听的socket的地址

 

读取数据:

ssise_t  recv(int sockfd , void *buf , size_t len , int flags)

recv读取sockfd上的数据,buflen代表数据的地址和大小,第四个参数通常啊设为0

 

发送数据:

ssise_t  send (int sockfd , void *buf , size_t len , int flags)

sendsockfd上写数据,buflen代表数据的地址和大小,第四个参数通常设为0

代码示例:

客户端:

#include<stdio.h>#include<string.h>#include<unistd.h>#include<stdlib.h>#include<assert.h>#include<sys/types.h>#include<sys/socket.h>#include<arpa/inet.h>void main(){    int sockfd=socket(AF_INET,SOCK_STREAM,0);    assert(sockfd!=-1);    struct sockaddr_in ser,cli;    ser.sin_family=AF_INET;    ser.sin_port=htons(6000);//5000一下谨生使用 1024是电脑自身使用    ser.sin_addr.s_addr=inet_addr("127.0.0.1");    int res=bind(sockfd,(struct sockaddr*)&ser,sizeof(ser));    assert(res!=-1);    listen(sockfd,5);    while(1)    {      int len=sizeof(cli);      int c=accept(sockfd,(struct sockaddr*)&cli,&len);      assert(c!=-1);      char buff[128]={0};      recv(c,buff,127,0);      printf("recv:%s\n",buff);      send(c,"ok",strlen("ok"),0);      if(strncmp(buff,"end",3)==0)      {          break;      }             send(c,"ok",strlen("ok"),0);      if(strncmp(buff,"end",3)==0)      {          break;      }      close(c);    }    close(sockfd);}             
客户端:

#include<stdio.h>#include<string.h>#include<unistd.h>#include<stdlib.h>#include<assert.h>#include<sys/types.h>#include<sys/socket.h>#include<arpa/inet.h>void main(){    int sockfd=socket(AF_INET,SOCK_STREAM,0);    assert(sockfd!=-1);    struct sockaddr_in ser,cli;    ser.sin_family=AF_INET;    ser.sin_port=htons(6000);//5000一下谨生使用 1024是电脑自身使用    ser.sin_addr.s_addr=inet_addr("127.0.0.1");    int res=connect(sockfd,(struct sockaddr*)&ser,sizeof(ser));    assert(res!=-1);    while(1)    {printf("please input\n");        char buff[128]={0};       fgets(buff,127,stdin);       send(sockfd,buff,strlen(buff),0);       recv(sockfd,buff,127,0);       printf("recv:%s\n",buff);}    close(sockfd);}          



原创粉丝点击