参考《TCP/IP网络编程》第二章,基于C++11进行实现
服务器端代码:
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <sys/socket.h>
#include <sys/unistd.h>
#include <sys/types.h>
#include <sys/errno.h>
#include <netinet/in.h>
#include <signal.h>
#include <iostream>
#include <string>
using std::cout;
using std::cin;
using std::string;
using std::endl;
#define BUFFSIZE 30
#define DEFAULT_PORT 9190 // 指定端口为 9190
#define LOG_BUFFSIZE 65536
int main()
{
int serv_sock; // 用于存放套接字,即ip和端口
int clnt_sock;
struct sockaddr_in serv_addr;
struct sockaddr_in clnt_addr;
socklen_t clnt_addr_size;
char message[BUFFSIZE] = "hello";
//调用 socket 函数创建套接字
serv_sock = socket(PF_INET, SOCK_STREAM, 0);
if(serv_sock == -1)
cout <<"Create socket error" << errno << ": " << strerror(errno) << endl;
bzero(&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); //0.0.0.0
serv_addr.sin_port = htons(DEFAULT_PORT);
//调用 bind 函数分配ip地址和端口号
if(bind(serv_sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1)
cout << "Bind error" << errno << ": " << strerror(errno) << endl;
//调用 listen 函数将套接字转为可接受连接状态
if(listen(serv_sock, 5) == -1)
cout << "Listen error" << errno << ": " << strerror(errno) << endl;
clnt_addr_size = sizeof(clnt_addr);
//调用 accept 函数受理连接请求。如果在没有连接请求的情况下调用该函数,则不会返回,直到有连接请求为止
clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_addr, &clnt_addr_size);
if(clnt_sock == -1)
cout << "Accept error" << errno << ": " << strerror(errno) << endl;
write(clnt_sock, message, sizeof(message));
close(clnt_sock);
close(serv_sock);
return 0;
}
客户端代码:
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <sys/socket.h>
#include <sys/unistd.h>
#include <sys/types.h>
#include <sys/errno.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <iostream>
#include <string>
using std::cout;
using std::cin;
using std::string;
using std::endl;
#define BUFFSIZE 2048
#define SERVER_IP "127.0.0.1" // 指定服务端的IP
#define SERVER_PORT 9190 // 指定服务端的port
int main()
{
int sock;
struct sockaddr_in serv_addr;
char message[300];
int str_len = 0;
int idx = 0, read_len = 0;
//创建套接字,此时套接字并不马上分为服务端和客户端。如果紧接着调用 bind,listen 函数,将成为服务器套接字
//如果调用 connect 函数,将成为客户端套接字
//若前两个参数使用PF_INET 和 SOCK_STREAM,则可以省略第三个参数 IPPROTO_TCP
sock = socket(PF_INET, SOCK_STREAM, 0);
if(sock == -1)
cout << "socket() error" << endl;
bzero(&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
inet_pton(AF_INET, SERVER_IP, &serv_addr.sin_addr);
serv_addr.sin_port = htons(SERVER_PORT);
//调用 connect 函数向服务器发送连接请求
if(connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1)
cout << "connect() error" << endl;
//当read函数返回0的时候条件为假,跳出循环
while(read_len = read(sock, &message[idx++], 1))
{
if(read_len == -1)
cout << "read error" << endl;
str_len += read_len;
}
cout << "Message from server: " << message << endl;
close(sock);
return 0;
}