/* File Name: client.c */
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <iostream>
using namespace std;
#define MAXLINE 4096
#define err_exit(m) \
do \
{\
perror(m);\
exit(EXIT_FAILURE);\
}while(0)
struct Packet
{
unsigned int msgLen; //数据部分的长度(注:这是网络字节序)
char text[1024]; //报文的数据部分
};
/**实现:
这两个函数只是按需多次调用read和write系统调用直至读/写了count个数据
**/
/**返回值说明:
== count: 说明正确返回, 已经真正读取了count个字节
== -1 : 读取出错返回
< count: 读取到了末尾
**/
ssize_t readn(int fd, void *buf, size_t count)
{
size_t nLeft = count;
ssize_t nRead = 0;
char *pBuf = (char *)buf;
while (nLeft > 0)
{
if ((nRead = read(fd, pBuf, nLeft)) < 0)
{
//如果读取操作是被信号打断了, 则说明还可以继续读
if (errno == EINTR)
continue;
//否则就是其他错误
else
return -1;
}
//读取到末尾
else if (nRead == 0)
return count-nLeft;
//正常读取
nLeft -= nRead;
pBuf += nRead;
}
return count;
}
/**返回值说明:
== count: 说明正确返回, 已经真正写入了count个字节
== -1 : 写入出错返回
**/
ssize_t writen(int fd, const void *buf, size_t count)
{
size_t nLeft = count;
ssize_t nWritten = 0;
char *pBuf = (char *)buf;
while (nLeft > 0)
{
if ((nWritten = write(fd, pBuf, nLeft)) < 0)
{
//如果写入操作是被信号打断了, 则说明还可以继续写入
if (errno == EINTR)
continue;
//否则就是其他错误
else
return -1;
}
//如果 ==0则说明是什么也没写入, 可以继续写
else if (nWritten == 0)
continue;
//正常写入
nLeft -= nWritten;
pBuf += nWritten;
}
return count;
}
bool sendMessage(int sockfd,Packet buf){
unsigned int lenHost = strlen(buf.text);
buf.msgLen = htonl(lenHost);
if (writen(sockfd, &buf, sizeof(buf.msgLen)+lenHost) == -1)
return false;
return true;
}
int InitStart(const char* ip,int port){
int sockfd;
struct sockaddr_in servaddr;
if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
return -1;
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(port);
if(inet_pton(AF_INET, ip, &servaddr.sin_addr) <= 0)
return -1;
if( connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0)
return -1;
return sockfd;
}
void hander(int sockfd,Packet buf){
cout<<"这里是处理函数"<< buf.text<<endl;
cin>>buf.text;
sendMessage(sockfd,buf);
}
bool ReadMessage(int sockfd){
struct Packet buf;
memset(&buf, 0, sizeof(buf));
//首先读取首部
ssize_t readBytes = readn(sockfd, &buf.msgLen, sizeof(buf.msgLen));
if (readBytes == -1){
cout<<"read socket error"<<endl;
close(sockfd);
return false;
}else if (readBytes != sizeof(buf.msgLen))
{
cout << "server connect closed... \nexiting..." << endl;
close(sockfd);
return false;
}
//然后读取数据部分
int lenHost = ntohl(buf.msgLen);
readBytes = readn(sockfd, buf.text, lenHost);
if (readBytes == -1){
err_exit("read socket error");
close(sockfd);
return false;
}else if (readBytes != lenHost)
{
cerr << "server connect closed... \nexiting..." << endl;
close(sockfd);
return false;
}
hander(sockfd,buf);
//cout << buf.text<<endl;
return true;
}
int main(int argc, char** argv)
{
int sockfd = InitStart("127.0.0.1",8000);
if(sockfd == -1){
cout<<"服务器连接失败!"<<endl;
return 0;
}
Packet buf;
cin>>buf.text;
sendMessage(sockfd,buf);
while (ReadMessage(sockfd));
cout<<"exit"<<endl;
close(sockfd);
exit(0);
}
socket 客户端 linux
最新推荐文章于 2025-04-26 16:30:54 发布