网络编程--tcp

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhuizhuzijidemenglsy/article/details/78461062

网络编程:

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);
}
          



猜你喜欢

转载自blog.csdn.net/zhuizhuzijidemenglsy/article/details/78461062