1.目录结构
->include //存放.h头文件
->source //存放.cpp源文件
->out //存放可执行文件
->makefile //一键执行
2.源码
2.1 Client.h
#ifndef _Client_H_
#define _Client_H_
#define INVALID_SOCKET -1
#define MAX_IP_ADDR_LENTH 32
#define MAX_PORT_LENTH 8
#define MAX_REV_BUFF_SIZE 1024
#define MAX_SED_BUFF_SIZE 1024
#include <iostream>
#endif
2.2 Client.cpp
#include "Client.h"
#include <errno.h> //perror 打印一些错误信息
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <unistd.h> //提供close方法
#include <arpa/inet.h> // 提供 inet_addr
#include <cstdlib> //atoi 将字符串数组转化为数字
#include <string.h>
#include "tcp_common.h"
int main(int argc, char *argv[])
{
if(argc < 2)
{
std::cout<<"[Usage:] ip prot"<<std::endl;
std::cout<<"./client 10.234.19.202 15001"<<std::endl;
return -1;
}
char IP_ADDR[MAX_IP_ADDR_LENTH] = { 0 };
char PORT[MAX_PORT_LENTH] = { 0 };
strncpy(IP_ADDR ,argv[1] , MAX_IP_ADDR_LENTH);
strncpy(PORT, argv[2], MAX_PORT_LENTH);
int client_port = atoi(PORT);
std::cout << "ip = " << IP_ADDR << std::endl;
std::cout << "port = " << PORT << std::endl;
std::cout << "client_port = " << client_port << std::endl;
//待优化得是对输入得ip和port先进行简单得判断,不需要等到绑定端口IP失败才返回
int Client_Socket_Fd;
Client_Socket_Fd = socket(AF_INET, SOCK_STREAM, 0);
if (INVALID_SOCKET == Client_Socket_Fd)
{
std::cout << "sock creat failed!" << std::endl;
return -1;
}
sockaddr_in Server_addr_;
Server_addr_.sin_addr.s_addr = inet_addr((const char *)IP_ADDR);
Server_addr_.sin_family = AF_INET;
Server_addr_.sin_port = htons(client_port);
while (1)
{
std::cout << "begin to connect!" << std::endl;
if (connect(Client_Socket_Fd, (sockaddr*)&Server_addr_, sizeof(sockaddr_in)) != 0)
{
perror("connect");
printf("connect failed , wait for reconnect!\n");
sleep(1);
}
else
{
std::cout << " connected!" << std::endl;
char buff_rev[MAX_REV_BUFF_SIZE] = { 0 };
int buflen = recv(Client_Socket_Fd, buff_rev, MAX_REV_BUFF_SIZE, 0);
if(buflen < 0)
{
std::cout << "receive message:" << buff_rev << std::endl;
}
/*char buff_send[MAX_SED_BUFF_SIZE] = { 0 };*/
student student_send = {0};
std::cout << "Please input name: ";
std::string t_name;
getline(std::cin, t_name);
memcpy(student_send.name,t_name.c_str(),sizeof(student_send.name));
std::cout << "Please input age:";
//char *t_age ; //野指针只想得位置不确定
//fgets(t_age,4, stdin); //fgets会把标准输入得内容放到内存得某个区域,如果t_age指向得时不可读不可写得区域都会导致段错误
//student_send.age = atoi((const char * )t_age);
//那为什么直接char *t_age = "sdasdas";就不会出错呢? 因为"sdasdas"这个字符串是存储在静态区得,所以这个指针也就不是野指针了
char t_age[4];
fgets(t_age,4,stdin);
student_send.age = atoi((const char *)t_age);
std::cout << "Please input sex(female or male):";
std::string t_sex;
getline(std::cin,t_sex );
std::cout << "t_sex = " << t_sex << std::endl;
if (!strcmp(t_sex.c_str(),"female" ))
{
student_send.sex = FEMALE;
}
else if (!strcmp(t_sex.c_str(),"male"))
{
student_send.sex = MALE;
}
else
{
std::cout << "dsdad";
student_send.sex = INVALID;
}
//stricmp() 用来比较字符串,不区分大小写;区分大小写比较字符串请查看strcmp()。
student_send.printStudent();
send(Client_Socket_Fd, (void *)&student_send, sizeof(student), 0);
//break;
}
}
close(Client_Socket_Fd);
return 0;
}