服务器端
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
int main(int argc, char *argv[]){
if(argc != 3){
fprintf(stderr, "Usage: %s <IP> <Port>\n", argv[0]); // 修正:提供完整的错误信息
exit(EXIT_FAILURE);
}
struct sockaddr_in my_addr, oth_addr;
ssize_t recv_data;
char buf[250];
int socket_ret = socket(AF_INET, SOCK_STREAM, 0);
if(socket_ret < 0){
perror("socket"); // 修正:提供完整的错误信息
exit(EXIT_FAILURE);
}
memset(&my_addr, 0, sizeof(my_addr)); // 修正:使用memset替代bzero
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(atoi(argv[2])); // 注意:如果atoi(argv[2])结果过大,可能会溢出
my_addr.sin_addr.s_addr = inet_addr(argv[1]); // 注意:如果argv[1]不是有效的IP地址,这里会返回INADDR_NONE
if(bind(socket_ret, (const struct sockaddr *)&my_addr, sizeof(my_addr)) < 0){
perror("bind"); // 修正:提供完整的错误信息
exit(EXIT_FAILURE);
}
if(listen(socket_ret, 10) < 0){
perror("listen"); // 修正:提供完整的错误信息
exit(EXIT_FAILURE);
}
socklen_t len = sizeof(oth_addr);
while(1){
int client_socket = accept(socket_ret, (struct sockaddr *)&oth_addr, &len); // 修正:使用更明确的变量名
if(client_socket < 0){
perror("accept"); // 修正:提供完整的错误信息
continue; // 修正:不退出程序,而是继续监听
}
printf("客户端地址为: %s\n", inet_ntoa(oth_addr.sin_addr)); // 修正:添加换行符\n
memset(buf, 0, sizeof(buf)); // 修正:使用memset替代bzero
while (1)
{
recv_data = recv(client_socket, buf, sizeof(buf) - 1, 0); // 修正:使用client_socket接收数据,并确保buf不会溢出
if(recv_data > 0){
printf("客户端发来:%s\n", buf); // 修正:添加换行符\n
}
}
//close(client_socket); // 修正:关闭客户端套接字
}
// 注意:正常情况下,服务器套接字不应该在这里关闭,因为它需要持续监听新的连接
// close(socket_ret); // 这行代码应该被注释掉或移除
return 0;
}
客户端
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
int main(int argc, char *argv[]){
if(argc != 3){
fprintf(stderr, "Usage: %s <IP> <Port>\n", argv[0]); // 修正:提供完整的错误信息
exit(EXIT_FAILURE);
}
struct sockaddr_in my_addr, oth_addr;
ssize_t recv_data;
char buf[250];
int socket_ret = socket(AF_INET, SOCK_STREAM, 0);
if(socket_ret < 0){
perror("socket"); // 修正:提供完整的错误信息
exit(EXIT_FAILURE);
}
memset(&my_addr, 0, sizeof(my_addr)); // 修正:使用memset替代bzero
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(atoi(argv[2])); // 注意:如果atoi(argv[2])结果过大,可能会溢出
my_addr.sin_addr.s_addr = inet_addr(argv[1]); // 注意:如果argv[1]不是有效的IP地址,这里会返回INADDR_NONE
/*
客户端不用绑定地址
if(bind(socket_ret, (const struct sockaddr *)&my_addr, sizeof(my_addr)) < 0){
perror("bind"); // 修正:提供完整的错误信息
exit(EXIT_FAILURE);
}
*/
/*客户端不用监听
if(listen(socket_ret, 10) < 0){
perror("listen"); // 修正:提供完整的错误信息
exit(EXIT_FAILURE);
}
*/
int connect_ret = connect(socket_ret, (const struct sockaddr *)&my_addr, sizeof(my_addr));
if (connect_ret < 0)
{
perror("connect");
exit(1);
}
//socklen_t len = sizeof(oth_addr);
while(1){
/*
客户端不需要等待自己连接
int client_socket = accept(socket_ret, (struct sockaddr *)&oth_addr, &len); // 修正:使用更明确的变量名
if(client_socket < 0){
perror("accept"); // 修正:提供完整的错误信息
continue; // 修正:不退出程序,而是继续监听
}
*/
//printf("客户端地址为: %s\n", inet_ntoa(oth_addr.sin_addr)); // 修正:添加换行符\n
memset(buf, 0, sizeof(buf)); // 修正:使用memset替代bzero
while (1)
{
fgets(buf, sizeof(buf), stdin);
recv_data = send(socket_ret, buf, sizeof(buf) - 1, 0); // 修正:使用client_socket接收数据,并确保buf不会溢出
//if(recv_data > 0){
// printf("服务器发来:%s\n", buf); // 修正:添加换行符\n
//}
}
//close(client_socket); // 修正:关闭客户端套接字
}
// 注意:正常情况下,服务器套接字不应该在这里关闭,因为它需要持续监听新的连接
// close(socket_ret); // 这行代码应该被注释掉或移除
return 0;
}