1.多个客户端可以向一个服务器发送连接请求
在服务器能够显示当前是哪个IP地址和端口连上服务器显示客户端发送消息的ip+端口
服务端
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
int running = 1;
void *client_handler(void *arg) {
int acc_fd = *((int *)arg);
char *buf=malloc(100);
struct sockaddr_in client_addr;
socklen_t client_addr_len = sizeof(client_addr);
if (getpeername(acc_fd, (struct sockaddr *)&client_addr, &client_addr_len) == 0) {
char client_ip[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &(client_addr.sin_addr), client_ip, INET_ADDRSTRLEN);
printf("客户端IP: %s, 端口: %d\n", client_ip, ntohs(client_addr.sin_port));
}
while (1) {
memset(buf, 0, 100);
recv(acc_fd, buf,100, 0);
printf("来自客户端[%s:%d]的消息:%s\n",inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), buf);
if(strcmp(buf,"gun\n")==0)
{
break;
}
}
close(acc_fd);
return NULL;
}
int main(int argc, char **argv) {
int sock_fd = socket(AF_INET, SOCK_STREAM, 0);
if (sock_fd == -1) {
perror("创建套接字失败");
return -1;
}
struct sockaddr_in serve;
serve.sin_family = AF_INET;
serve.sin_port = htons(atoi(argv[2]));
serve.sin_addr.s_addr = inet_addr(argv[1]);
bind(sock_fd, (struct sockaddr *)&serve, sizeof(serve));
int listen_ret = listen(sock_fd, 4);
printf("等待连接....\n");
while (running) {
int acc_fd = accept(sock_fd, NULL, NULL);
if (acc_fd == -1) {
perror("接受连接失败");
continue;
}
printf("连接成功!!!\n");
pthread_t thread_id;
pthread_create(&thread_id, NULL, client_handler, &acc_fd);
pthread_detach(thread_id);
}
close(sock_fd);
return 0;
}
客户端
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
int main(int argc,char **argv)
{
//1.创建套接字
int sock_fd = socket(AF_INET, SOCK_STREAM, 0);
//网际协议,套接字类型TCP选择流式套接字
if(-1 == sock_fd)
{
perror("creat sock_fd failed");
return -1;
}
//2.绑定服务器地址
struct sockaddr_in serve;
serve.sin_family = AF_INET;//地址族成员
serve.sin_port = htons(atoi(argv[2]));//0-------65535 (0----5000,大型企业,5000-----10000,留给将来的大型企业,10000-----65535,才是留给我们的)
serve.sin_addr.s_addr = inet_addr(argv[1]);//需要把点分式字符串转换为无符号的32位网络地址in_addr_t,
//绑定函数
int ret = bind(sock_fd, (struct sockaddr *)&serve, sizeof(serve));
if(ret == -1)
{
perror("bind failed");
}
//3.发起连接(connect)
connect(sock_fd,(struct sockaddr *)&serve,sizeof(serve));
char *buf = malloc(100);
while(1)
{
memset(buf,0,100);
fgets(buf,100,stdin);
//4.发送消息(send)
send(sock_fd,buf,100,0);
if(strcmp(buf,"gun\n")==0)
{
break;
}
}
close(sock_fd);
}