经过了一个多星期的学习,我在这里总结一下关于Linux,Windows的socket TCP通信的不同情形。
-
server,client之间的通信
https://blog.csdn.net/wesigj/article/details/99294538 -
Socket之TCP全双工Server-Client通信
https://blog.csdn.net/wesigj/article/details/99322695 -
client,client之间的通信
-
一个小应用-------网络聊天室https://blog.csdn.net/wesigj/article/details/99418596
-
Linux与Windows之间的socket通信
-
socket实现两台pc之间的数据传输功能,包括windows到linux,TCP/IP
三、聊天室的应用
实际上,client与client之间的通信是可以用一个两个人的聊天室来替代的。在我的认识中,client与client之间应该需要一个服务器来控制收发信息,那么就是server接收两个client之后,通过recv与send函数来发送接收信息。
其实,使用多线程也是一种合适的方法,使用fork函数,创建子线程,来send和recv。
或者使用read函数,和write函数来send recv
fgets 和 fputs函数 来通信
按正常来说,我们应该是使用send函数和recv函数来通信,其他的比较投机取巧。
server
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#define PORT 8000
#define MAX_MAN 20
#define MAX_BUFFER_SIZE 128
int sockfd;
int connectfd[MAX_MAN];
//define DEBUG_PRINT
#ifdef DEBUG_PRINT
#define DEBUG(format, ...) printf("FILE: "__FILE__"), LINE: %d: "format"\n", __LINE__, ##__VA_ARGS__)
#else
#define DEBUG(format, ...)
#endif
void quit();
void recv_send(int numble);
int main(int argc, char const *argv[])
{
char server_buff[MAX_BUFFER_SIZE];
time_t ticks;
int i;
pthread_t thread;
struct sockaddr_in server_addr,client_addr;
printf("waiting for connect\n(enter ""exit"" to quit)");
//define addr
DEBUG("=== initialize...");
memset(&server_addr,0,sizeof(struct sockaddr_in));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
DEBUG("=== socket...");
//define sockfd
sockfd = socket(AF_INET,SOCK_STREAM,0);
if (sockfd< 0)
{
perror("socket");
exit(1);
}
DEBUG("=== bind...");
if(bind(sockfd,(struct sockaddr *)&server_addr,sizeof(server_addr)) < 0)
{
perror("bind");
exit(1);
}
DEBUG("=== listening...");
listen(sockfd,MAX_MAN);
//pthread_create QUIT
pthread_create(&thread,NULL,(void *)(quit),NULL);
memset(&connectfd,-1,sizeof(connectfd));
while(1)
{
int length;
for(i=0;i<MAX_MAN;i++)
{
if(connectfd[i] == -1)
break;
}
connectfd[i] = accept(sockfd, (struct sockaddr *)&client_addr,&length);
if(connectfd[i] < 0)
{
perror("accept");
}
ticks = time(NULL);
printf("%.24s\n\tconnect from : %s,port %d\n",
ctime(&ticks),
inet_ntop(AF_INET,&(client_addr.sin_addr),server_buff,MAX_BUFFER_SIZE ),
ntohs(client_addr.sin_port)
);
//pthread_create recv send
pthread_create(malloc(sizeof(pthread_t)),NULL,(void *)(&recv_send),(void *)i);
}
return 0;
}
void quit()
{
char message[10];
while(1)
{
scanf("%s",message);
if(strcmp(message, "quit") == 0)
{
printf("goodbye everyome\n");
close(sockfd);
exit(0);
}
}
}
void recv_send(int numble)
{
int len, i;
char name[32], mytime[32], buf[MAX_BUFFER_SIZE];
time_t ticks;
int ret;
// 获取此线程对应的套接字用户的名字
write(connectfd[numble], "your name: ", strlen("your name: "));
len = read(connectfd[numble], name, 32);
if(len > 0)
name[len-1] = '\0'; // 去除换行符
strcpy(buf, name);
strcat(buf, "\tjoin in\n\0");
// 把当前用户的加入 告知所有用户
for(i=0; i<MAX_MAN; i++)
{
if(connectfd[i] != -1)
write(connectfd[i], buf, strlen(buf));
}
while(1)
{
char temp[MAX_BUFFER_SIZE];
if((len=read(connectfd[numble], temp, MAX_BUFFER_SIZE)) > 0)
{
temp[len-1] = '\0';
// 当用户输入bye时,当前用户退出
if(strcmp(temp, "bye") == 0)
{
close(connectfd[numble]);
connectfd[numble] = -1;
pthread_exit(&ret);
}
ticks = time(NULL);
sprintf(mytime, "%.24s\r\n", ctime(&ticks));
//write(connfd[n], mytime, strlen(mytime));
strcpy(buf, name);
strcat(buf, "\t");
strcat(buf, mytime);
strcat(buf, "\r\t");
strcat(buf, temp);
strcat(buf, "\n");
for(i=0; i<MAX_MAN; i++)
{
if(connectfd[i] != -1)
write(connectfd[i], buf, strlen(buf));
}
}
}
}
client
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define MAX_BUFFER_SIZE 128
#define HOST_IP "127.1.1.0"
#define PORT 8000
void send_message();
int sockfd;
int main(int argc, char const *argv[])
{
pthread_t thread;
struct sockaddr_in client_addr;
char buffer[MAX_BUFFER_SIZE];
memset(&client_addr,0,sizeof(struct sockaddr_in));
client_addr.sin_family = AF_INET;
client_addr.sin_port = htons(PORT);
client_addr.sin_addr.s_addr = inet_addr(HOST_IP);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
perror("socket");
exit(1);
}
printf("connect to server\n");
if (connect(sockfd, (struct sockaddr *)&client_addr,sizeof(client_addr)) < 0)
{
perror("connect");
exit(1);
}
//pthread_create
pthread_create(&thread,NULL,(void *)(&send_message),NULL);
while(1)
{
int length;
if((length = read(sockfd,buffer,MAX_BUFFER_SIZE)) > 0)
{
buffer[length] = '\0';
printf("\n%s",buffer );
fflush(stdout);
}
}
return 0;
}
void send_message()
{
char name[32];
char buffer[MAX_BUFFER_SIZE];
fgets(name,32,stdin);
write(sockfd,name,strlen(name));
while(1)
{
fgets(buffer,MAX_BUFFER_SIZE,stdin);
write(sockfd,buffer,strlen(buffer));
if (strcmp(buffer,"bye\n") == 0)
{
exit(0);
}
}
}
用了差不多一个多星期来学习Linux,socket,TCP通信。对TCP通信有了浅显的了解。在下次的时候,我会将学到的东西总结一下。
参考资料
代码