自己写的一个简单聊天小程序,运用了socket编程和多线程。服务端负责接收信息同时转发信息,客户端负责发送消息同时接收服务端发来的信息
**客户端**
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
static int
connect_to_server (struct in_addr *ipaddr)
{
int sock, ret;
struct sockaddr_in addr;
sock = socket (AF_INET, SOCK_STREAM, 0);
if ( sock == -1 ) {
printf ("ERROR: Cannot create server socket!\n");
return -1;
}
memset (&addr, 0, sizeof (struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_port = htons (7799);
memcpy (&addr.sin_addr, ipaddr, sizeof (struct in_addr));
ret = connect (sock, (struct sockaddr *)&addr,
sizeof (struct sockaddr_in));
if ( ret == -1 ) {
printf ("ERROR: Cannot connect to server!\n");
close (sock);
return -1;
}
return sock;
}
void* Revmeg(void* sock)
{
char buf[1024];
int sock_id = *(int*)sock;
while (1)
{
memset(buf, 0, sizeof(buf));
int ret = recv(sock_id, buf, 1024, 0);
if(ret>0)
printf("Received data:%s\n", buf);
}
}
int main (int argc, char *argv[])
{
int sock, ret;
char rev[1024];
char sen[1024];
struct in_addr ipaddr;
socklen_t recvlen;
system("systemctl stop firewalld.service");//关闭防火墙
if ( argc <= 1 ) {
printf ("ERROR:Please input <IPADDR> \n");
return 1;
}
ret = inet_aton (argv[1], &ipaddr);
if ( ret == 0 ) {
printf ("Usage: %s <IPADDR> <MESSAGE> ...\n", argv[0]);
return 1;
}
sock = connect_to_server (&ipaddr);//创建客户端socket
if ( sock == -1 )
return 1;
else
printf ("Connect to server successfully.\n");
pthread_t pid;
pthread_create(&pid,NULL,Revmeg,&sock);
while(1)
{
gets(sen);
if (!strcmp(sen, "quit")){
send(sock, sen, sizeof(sen), 0);
break; }
send(sock, sen, sizeof(sen), 0);
}
close (sock);
printf ("Connection closed.\n");
return 0;
}
**服务器**
```c
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define MAXLINE 10//最大连接数为10
int client[MAXLINE];//建立连接的client
static int
get_sersocket ()//创建服务器socket
{
int sock, ret;
struct sockaddr_in addr;
sock = socket (PF_INET, SOCK_STREAM, 0);
if ( sock == -1 ) {
printf ("ERROR: Cannot create server socket!\n");
return -1;
}
memset (&addr, 0, sizeof (struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_port = htons (7799);
addr.sin_addr.s_addr = htonl (INADDR_ANY);
ret = bind (sock, (struct sockaddr *)&addr, sizeof (struct sockaddr_in));
if ( ret < 0 ) {
printf ("ERROR: Cannot bind port to server socket!\n");
close (sock);
return -1;
}
return sock;
}
static int
connect_with_client (int sersock)//建立连接
{
int commsock, ret;
struct sockaddr_in caddr;
socklen_t addrlen;
ret = listen (sersock, MAXLINE);//监听连接请求
if ( ret == -1 ) {
printf ("ERROR: Cannot wait to connected.\n");
return -1;
}
printf ("Waiting to connected...\n");
addrlen = sizeof (struct sockaddr_in);
commsock = accept (sersock, (struct sockaddr *)&caddr, &addrlen);//接收连接请求
if ( commsock == -1 ) {
printf ("ERROR: Connect with client failed!\n");
return -1;
}
printf ("Connected with client %s:%d\n",
inet_ntoa (caddr.sin_addr), ntohs (caddr.sin_port));
return commsock;
}
void* clientmge(void* sock)接收客户端信息,并转发
{
char buf[1024];
int socket_id = *(int*)sock;//客户端socket标识符
while (1)
{
memset(buf, 0, sizeof(buf));
int ret = recv(socket_id, buf, 1024, 0);
if (ret > 0)
{ if (!strcmp(buf, "quit")){
close(socket_id);
printf("One connection is closed\n");
}
printf("Received data:%s\n", buf);
for (int i = 0; i < MAXLINE; i++)
{
send(client[i], buf, sizeof(buf), 0);
}
}
}
}
int main ()
{
int sersock, commsock,n=1;
char rev[1024] = { '\0' };
socklen_t recvlen;
system("systemctl stop firewalld.service");//关闭防火墙
sersock = get_sersocket ();//创建服务器socket
if ( sersock == -1 )
return 1;
while ( 1 ) {
client[n] = connect_with_client (sersock);//建立连接的client
if ( client[n] == -1 ) {
close (sersock);
return 1;
}
pthread_t th;
pthread_create(&th, NULL, clientmge, &client[n]);//接收客户端信息,并转发
n++;
if(n>MAXLINE){
printf("The server is busy, please connect later");
close (client[n]);
}
}
for(int i=0;i<MAXLINE;i++)
close (client[i]);
close (sersock);
return 0;
}