Linux-C语言编写-TCP客户端发送消息流程(含代码)简介(2)

目录

第一步socket

第二步struct sockaddr_in

第三步connect

第四步send

第五步close

详细代码


第一步socket

1.操作:创建流式套接字;

2.所用函数:socket;

        socket(AF_INET,SOCK_STREAM,0);

3.函数参数:AF_INET代表所使用的网际协议版本ipv4;

        SOCK_STREAM代表创建的是流式套接字;

        0为自动匹配该项;

4.返回值:sockfd返回值小于0时,创建失败;

int sockfd;
sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd < -1)
{
    perror("socket err");
    return -1;
}
printf("socket sucess\n");

第二步struct sockaddr_in

1.操作:填充结构体;

2.结构体:struct sockaddr_in;

要填充的成员变量:sin_family - 所使用的网际协议版本;

sin_port - 端口号;sin_addr.s_addr - ip;

struct sockaddr_in serveraddr,clientaddr;
serveraddr.sin_family = AF_INET; //使用的是ipv4地址
//htons函数将主机字节序转换为网络字节序,atoi函数将字符串端口号转换为数字端口号
serveraddr.sin_port = htons(atoi(argv[1])); 
serveraddr.sin_addr.s_addr = inet_addr("0.0.0.0");//32位的IP地址

第三步connect

1.操作:连接服务器;

2.所用函数:connect;

        connect(sockfd,(struct sockaddr *)&serverddr,sizeof(serveraddr));

3.函数参数:

sockfd - 套接字描述符;

(struct sockaddr *)&serveraddr - 服务器地址;

sizeof(serveraddr) - 服务器地址大小;

4.返回值:connect返回值小于0时,绑定失败;

int connect_t;
connect_t = connect(sockfd, (struct sockaddr *)&clientaddr, sizeof(clientaddr));
if (connect_t < 0)
{
	perror("connect err");
	return -1;
}
printf("connect sucess\n");

第四步send

1.操作:向服务器发送消息;

2.所用函数:send;

        send(sockfd,buf,sizeof(buf),0);

3.函数参数:

sockfd - 套接字描述符;

buf - 发送的数据保存在该数组;

sizeof(buf) - 数组大小;

0 - 与recv的参数作用相同,起堵塞和非堵塞的作用;

fgets(buf, sizeof(buf), stdin);
if (buf[strlen(buf) - 1] == '\n')
{
	buf[strlen(buf) - 1] = '\0';
}
send(sockfd, buf, sizeof(buf), 0);

第五步close

1.操作:关闭描述符;

2.所用函数:close;

        close(sockfd);
 

详细代码


/********
*客户端代码
*client.c
*********/

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <wait.h>

int main(int argc, char const *argv[])
{
	if (argc != 3)
	{
		printf("input %s <ip> <port>\n", argv[0]);
		return -1;
	}
	char buf[128] = "";
	//1.创建流式套接字 socket
	int sockfd;
	sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (sockfd < -1)
	{
		perror("socket err");
		return -1;
	}
	printf("socket sucess\n");

	//2
	//填充结构体
	struct sockaddr_in clientaddr;
	clientaddr.sin_family = AF_INET;				 //使用ipv4地址
	clientaddr.sin_port = htons(atoi(argv[2]));		 //主机字节序到网络字节序
	clientaddr.sin_addr.s_addr = inet_addr(argv[1]); //32位的IP地址

	//3.连接服务器
	int connect_t;
	connect_t = connect(sockfd, (struct sockaddr *)&clientaddr, sizeof(clientaddr));
	if (connect_t < 0)
	{
		perror("connect err");
		return -1;
	}
	printf("connect sucess\n");

	//4.发送数据
	while (1)
	{
		fgets(buf, sizeof(buf), stdin);
		if (buf[strlen(buf) - 1] == '\n')
		{
			buf[strlen(buf) - 1] = '\0';
		}
		send(sockfd, buf, sizeof(buf), 0);
		if (strncmp(buf, "quit", 4) == 0)
		{
			break;
		}
    }
	//关闭
	close(sockfd);
	return 0;
}

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
服务器代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> #include <unistd.h> #include <pthread.h> #define MAX_CLIENTS 10 #define BUFFER_SIZE 1024 int client_count = 0; // 客户端数量 int client_sockets[MAX_CLIENTS]; // 客户端套接字 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // 互斥锁 // 发送消息给所有客户端,除了发送者 void broadcast(char *message, int sender_socket) { pthread_mutex_lock(&mutex); // 加锁 for (int i = 0; i < client_count; i++) { int socket_fd = client_sockets[i]; if (socket_fd != sender_socket) { send(socket_fd, message, strlen(message), 0); } } pthread_mutex_unlock(&mutex); // 解锁 } // 发送消息给指定客户端 void send_to(char *message, int receiver_socket) { send(receiver_socket, message, strlen(message), 0); } // 处理客户端消息 void *handle_client(void *arg) { int client_socket = *(int *)arg; char buffer[BUFFER_SIZE]; while (1) { memset(buffer, 0, BUFFER_SIZE); int bytes_received = recv(client_socket, buffer, BUFFER_SIZE, 0); if (bytes_received <= 0) { // 客户端断开连接 pthread_mutex_lock(&mutex); for (int i = 0; i < client_count; i++) { if (client_sockets[i] == client_socket) { client_count--; for (int j = i; j < client_count; j++) { client_sockets[j] = client_sockets[j+1]; } break; } } pthread_mutex_unlock(&mutex); close(client_socket); break; } if (buffer[0] == '@') { // 私聊消息 char *username = strtok(buffer+1, " "); char *message = strtok(NULL, "\n"); int receiver_socket = -1; pthread_mutex_lock(&mutex); for (int i = 0; i < client_count; i++) { if (strcmp(username, inet_ntoa(((struct sockaddr_in *)&client_sockets[i])->sin_addr)) == 0) { receiver_socket = client_sockets[i]; break; } } pthread_mutex_unlock(&mutex); if (receiver_socket != -1) { char response[BUFFER_SIZE]; sprintf(response, "(私聊)%s: %s", inet_ntoa(((struct sockaddr_in *)&client_socket)->sin_addr), message); send_to(response, receiver_socket); } else { char response[BUFFER_SIZE]; sprintf(response, "用户 %s 不存在或不在线", username); send_to(response, client_socket); } } else { // 广播消息 char response[BUFFER_SIZE]; sprintf(response, "%s: %s", inet_ntoa(((struct sockaddr_in *)&client_socket)->sin_addr), buffer); broadcast(response, client_socket); } } return NULL; } int main(int argc, char *argv[]) { if (argc != 2) { printf("Usage: %s <port>\n", argv[0]); return -1; } int server_socket = socket(AF_INET, SOCK_STREAM, 0); if (server_socket == -1) { perror("socket"); return -1; } int port = atoi(argv[1]); struct sockaddr_in server_addr; server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = INADDR_ANY; server_addr.sin_port = htons(port); if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) { perror("bind"); close(server_socket); return -1; } if (listen(server_socket, MAX_CLIENTS) == -1) { perror("listen"); close(server_socket); return -1; } pthread_t tid; while (1) { struct sockaddr_in client_addr; socklen_t client_addr_len = sizeof(client_addr); int client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &client_addr_len); if (client_socket == -1) { perror("accept"); continue; } if (client_count == MAX_CLIENTS) { printf("已达到最大客户端数量\n"); close(client_socket); continue; } client_sockets[client_count++] = client_socket; printf("客户端 %s:%d 连接成功\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); pthread_create(&tid, NULL, handle_client, &client_socket); pthread_detach(tid); } close(server_socket); return 0; } ``` 客户端代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> #include <unistd.h> #include <pthread.h> #define BUFFER_SIZE 1024 int sock_fd; // 客户端套接字 char username[20]; // 用户名 // 接收服务器消息 void *receive_message(void *arg) { char buffer[BUFFER_SIZE]; while (1) { memset(buffer, 0, BUFFER_SIZE); int bytes_received = recv(sock_fd, buffer, BUFFER_SIZE, 0); if (bytes_received <= 0) { // 服务器断开连接 printf("与服务器断开连接\n"); close(sock_fd); exit(0); } printf("%s\n", buffer); } return NULL; } int main(int argc, char *argv[]) { if (argc != 3) { printf("Usage: %s <server_ip> <server_port>\n", argv[0]); return -1; } sock_fd = socket(AF_INET, SOCK_STREAM, 0); if (sock_fd == -1) { perror("socket"); return -1; } char *server_ip = argv[1]; int server_port = atoi(argv[2]); struct sockaddr_in server_addr; server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = inet_addr(server_ip); server_addr.sin_port = htons(server_port); if (connect(sock_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) { perror("connect"); close(sock_fd); return -1; } printf("请输入用户名: "); scanf("%s", username); pthread_t tid; pthread_create(&tid, NULL, receive_message, NULL); // 创建一个线程接收服务器消息 pthread_detach(tid); char buffer[BUFFER_SIZE]; while (1) { memset(buffer, 0, BUFFER_SIZE); fgets(buffer, BUFFER_SIZE, stdin); if (buffer[0] == '\n') { continue; } if (strcmp(buffer, "exit\n") == 0) { break; } if (buffer[0] == '@') { // 私聊消息 char *username = strtok(buffer+1, " "); char *message = strtok(NULL, "\n"); if (message != NULL) { char request[BUFFER_SIZE]; sprintf(request, "@%s %s\n", username, message); send(sock_fd, request, strlen(request), 0); } } else { // 广播消息 char request[BUFFER_SIZE]; sprintf(request, "%s\n", buffer); send(sock_fd, request, strlen(request), 0); } } close(sock_fd); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值