步驟
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;
}