1、服务端代码
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <error.h>
#include <unistd.h>
#include <netdb.h>
#define SERVER_PORT 9000
#define SERVER_ADDR "0.0.0.0"
#define MAX_LISTEN_NUM 20
#define MAX_MESSAGE_NUM 1024
int main(void)
{
int server_sock, client_sock;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
char recv_msg[MAX_MESSAGE_NUM] = {0};
int recv_data_num, addr_len, reuse;
/* int socket(int domain, int type, int protocol) */
server_sock = socket(AF_INET, SOCK_STREAM, 0);
if (server_sock < 0)
{
perror("creat socket fail");
return -1;
}
//设置套接字的属性使它能够在计算机重启的时候可以再次使用套接字的端口和IP
reuse = 1;
setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
server_addr.sin_addr.s_addr = inet_addr(SERVER_ADDR);
addr_len = sizeof(server_addr);
/* int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) */
if (bind(server_sock, (struct sockaddr *)&server_addr, addr_len))
{
perror("bind fail");
return -1;
}
/* int listen(int sockfd, int backlog) */
if (listen(server_sock, MAX_LISTEN_NUM) < 0)
{
perror("listen fail");
return -1;
}
printf("server ip: %s, listening port: %d\n", SERVER_ADDR, SERVER_PORT);
while (1)
{
printf("start accept client...\n");
/* int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) */
/* accep默认会阻塞进程,直到接收到client的连接请求并返回一个新的socket */
client_sock = accept(server_sock, (struct sockaddr *)&client_addr, (socklen_t*)&addr_len);
if (client_sock < 0)
{
perror("accept fail");
continue;
}
printf("accept client connect success!!\n");
printf("client ip: %s, port is %d\n", inet_ntoa(client_addr.sin_addr), htons(client_addr.sin_port));
while (1)
{
recv_data_num = recv(client_sock, (void *)recv_msg, MAX_MESSAGE_NUM, 0);
if (recv_data_num < 0)
{
perror("read fail");
continue;
}
recv_msg[recv_data_num] = '\0';
printf("server get client[%s] msg :%s\n", inet_ntoa(client_addr.sin_addr), recv_msg);
/* 输入“exit”时退出进程 */
if (strcmp("exit", recv_msg) == 0)
{
break;
}
}
}
close(server_sock);
return 0;
}
2、客户端代码
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <error.h>
#include <unistd.h>
#include <netdb.h>
#define MAX_MESSAGE_NUM 1024
#define SERVER_ADDR "127.0.0.1"
#define SERVER_PORT 9000
int main()
{
int client_sock;
char send_msg[MAX_MESSAGE_NUM];
struct sockaddr_in server_addr;
int addr_len;
client_sock = socket(AF_INET, SOCK_STREAM, 0);
if (client_sock < 0)
{
perror("accept fail");
return -1;
}
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(SERVER_ADDR);
server_addr.sin_port = htons(SERVER_PORT);
/* int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) */
if (connect(client_sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
{
perror("connect fail");
return -1;
}
printf("send message:\n");
while (1)
{
scanf("%s", send_msg);
send(client_sock, (void *)send_msg, strlen(send_msg), 0);
/* 当接收到“exit”时退出 */
if (strcmp("exit", send_msg) == 0)
{
break;
}
}
close(client_sock);
return 0;
}
3、测试结果