Linux網絡編程基礎:TCP客戶端程序實現

步驟

1)創建套接字文件描述符,指定使用TCP協議,注意客戶端socket函數直接創建的套接字文件直接用於通信
2)調用connect函數向服務器發起連接請求,相應的服務器調用accept函數接收連接請求,進行三次握手連接。三次握手的具體過程由TCP協議自動完成,程序員只需要調用connect與accept函數接口即可
connect函數
函數原型:

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

函數用於向服務器發起連接請求
函數成功:返回0
函數失敗:返回-1
connect函數參數
sockfd:用於通信的套接字文件描述符
addr:指向一個結構體變量,此變量存放服務器的端口和IP以及協議族
addrlen:上一個參數指向的結構體變量的大小
3)調用send函數發送數據
4)調用recv函數接收數據
示例:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <signal.h>
 
#define  SIP "192.168.239.128"  //存放服務器ip的宏
#define  SPROT 5006  //存放服務器進程端口的宏


/*封裝應用層數據,目前要發送的數據爲學生信息*/
typedef struct data
{
   unsigned int stu_num;
   char stu_nam[50];
}Data;

int sockfd = -1;  //套接字文件描述符爲全局變量

void print_err(char* str,int line,int err_no)  報錯函數
{ 
    printf("%d %s: %s\n",line,str,strerror(err_no));
    exit(-1);
}

void* pth_fun(void * pth_arg)   //次線程用於接收數據
{
      int ret = 0;
      Data stu_data = {0};   //定義接收數據的結構體變量
      while(1)
      {
          bzero(&stu_data,sizeof(stu_data));  //清空結構體
          ret = recv(sockfd,(void*)&stu_data,sizeof(stu_data),0); //接收
          if(ret >0)
          {
                  printf("student number:%d\n",ntohl(stu_data.stu_num));
                  printf("student name:%s\n",stu_data.stu_nam);
           }
          else if(ret == -1)
          print_err("recv fail",__LINE__,errno);
      }
}


int main()
{
    int ret = 0;
    /*創建套接字文件描述符,指定使用TCP協議*/
    /*注意客戶端socket函數直接創建的套接字文件直接用於通信*/
    sockfd = socket(PF_INET,SOCK_STREAM,0);
    if(sockfd == -1) print_err("socket fail",__LINE__,errno);

/*調用connect函數向服務器發起連接請求,相應的服務器調用accept函數接收連接請>求,進行三次握手連接*/
    struct sockaddr_in seraddr = {0};  //結構體變量
    seraddr.sin_family = AF_INET;   //協議族
    seraddr.sin_port   = htons(SPROT);  //服務器端口
    seraddr.sin_addr.s_addr = inet_addr(SIP);  //服務器IP
    ret = connect(sockfd,(struct sockaddr *)&seraddr,sizeof(seraddr));
    if(ret == -1)  print_err("connect fail",__LINE__,errno);
    //創建次線程
    pthread_t tid;
    ret = pthread_create(&tid,NULL,pth_fun,NULL);
    if(ret != 0)  print_err("pth_create fail",__LINE__,ret);
    //發送數據
    Data stu_data = {0};
    int tmp = 0;
    while(1)
    {
            bzero(&stu_data,sizeof(stu_data));
            //封入學生學號 
            printf("input student number = \n");
            scanf("%d",&tmp);
            stu_data.stu_num = htonl(tmp);
            //封入學生姓名
            printf("input student name = \n");
            scanf("%s",stu_data.stu_nam);
            //發送學生數據
            ret = send(sockfd,(void *)&stu_data,sizeof(stu_data),0);
            if(ret == -1)  print_err("send fail",__LINE__,errno);
    }
    return 0;
 }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章