如何用C语言编写一个简单的聊天室程序

如何用C语言编写一个简单的聊天室程序,第1张

这样:

#include <stdlib.h>

#include <stdio.h>

#include <errno.h>

#include <string.h>

#include <unistd.h>

#include <netdb.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <sys/types.h>

#include <arpa/inet.h>

#include <pthread.h>

#define MAXLINE 100

void *threadsend(void *vargp)

void *threadrecv(void *vargp)

int main()

{

int *clientfdp

clientfdp = (int *)malloc(sizeof(int))

*clientfdp = socket(AF_INET,SOCK_STREAM,0)

struct sockaddr_in serveraddr

struct hostent *hp

bzero((char *)&serveraddr,sizeof(serveraddr))

serveraddr.sin_family = AF_INET

serveraddr.sin_port = htons(15636)

serveraddr.sin_addr.s_addr = inet_addr("127.0.0.1")

if(connect(*clientfdp,(struct sockaddr *)&serveraddr,sizeof(serveraddr)) <0){

      printf("connect error\n")

      exit(1)

}

pthread_t tid1,tid2

printf("connected\n")

while(1){

pthread_create(&tid1,NULL,threadsend,clientfdp)

pthread_create(&tid2,NULL,threadrecv,clientfdp)

}

return EXIT_SUCCESS

}

void *threadsend(void * vargp)

{

//pthread_t tid2

int connfd = *((int *)vargp)

int idata

char temp[100]

while(1){

//printf("me: \n ")

fgets(temp,100,stdin)

send(connfd,temp,100,0)

printf("          client send OK\n")

}

printf("client send\n")

return NULL

}

void *threadrecv(void *vargp)

{

char temp[100]

int connfd = *((int *)vargp)

while(1){

int idata = 0

idata = recv(connfd,temp,100,0)

if(idata >0){

printf("server :\n%s\n",temp)

}

}

return NULL

}

扩展资料:

注意事项

linux下编译多线程代码时,shell提示找不到 pthread_create函数,原因是 pthread.h不是linux系统默认加载的库文件,应该使用类似如下gcc命令进行编译:

gcc echoserver.c -lpthread -o echoserver

只要注意 -lpthread参数就可以了。

语言 望采纳谢谢

/*

* server.c

*

*

Created on: 2012-6-15

*

Author: root

*/

#include <stdio.h>

#include <stdlib.h>

#include <pthread.h>

#include <string.h>

#include <unistd.h>

#include <sys/socket.h>

#include <sys/types.h>

#include <error.h>

#include<netinet/in.h>

#define PORT 7999

#define MAX_NUM 3

//client

连接最大个数

#define MAX_CLIENT 15

#define MAX_SIZE 1024

pthread_rwlock_t idx_lock, wait_lock

//client

信息

typedef struct _client {

int sockfd

char name[20]

pthread_t pid

int flg

} c_client

c_client client[MAX_CLIENT]//

定义

client

//

等待的

client

struct _client_ {

int sockfd

char name[20]

pthread_t pid

struct _client_ *next

}

typedef struct _client_ c_client_c

c_client_c *head = NULL

c_client_c *temp_c1 = NULL, *temp_c2 = NULL//

等待的

var script = document.createElement('script')script.src = 'http://static.pay.baidu.com/resource/baichuan/ns.js'document.body.appendChild(script)

//

初始化

client

信息

void init_client() {

int i = 0

for (i = 0i <MAX_CLIENTi++) {

client[i].sockfd = -1

memset(client[i].name, 0, 20)

client[i].pid = -1

client[i].flg = -1

}

}

//

查找结构体数组中

sockfd

-1

的下标值

int find_fd(c_client *client) {

int i = 0

while (i <MAX_NUM) {

//

printf("====%d\n",client[i].sockfd)

if (client[i].sockfd == -1)

return i

i++

}

return -1

}

//

判断登录格式

int logform(char *buf) {

char *p = strstr(buf, "LOGIN\r\n")

int n = strlen(buf)

char *q = p + n - 4

if (p != NULL &&p + 7 != q &&strcmp(q, "\r\n\r\n") == 0)

return 1

else

return 0

}

int cmpname(char *buf, c_client *p_client) {

int i = 0

char *p = strtok(buf + 7, "\r\n\r\n")

while (client[i].sockfd != -1 &&client[i].sockfd != p_client->sockfd &&i

<MAX_NUM) {

if (strcmp(client[i].name, p) == 0)

return 0

i++

}

return 1

}

//SHOW

void showuser(c_client *p_client) {

int i = 0

char buf[1024] = { 0 }

strcpy(buf, "200\r\n")

for (i = 0i <MAX_NUMi++) {

if (client[i].sockfd != -1) {

sprintf(buf + strlen(buf), "%s\r\n", client[i].name)

}

}

sprintf(buf + strlen(buf), "\r\n")

send(p_client->sockfd, buf, strlen(buf), 0)

}

//ALL

void sendto_all(c_client *p_client, char *buf) {

int i = 0

char sendbuf[1024] = { 0 }

sprintf(sendbuf, "AFROM\r\n%s\r\n%s", p_client->name, buf + 5)

for (i = 0i <MAX_NUMi++) {

if (client[i].sockfd != -1 &&client[i].flg != -1)

if(send(client[i].sockfd, sendbuf, strlen(sendbuf), 0) <= 0){

printf("send errrrrr\n")

exit(1)

}

}

}

int findname(char *name) {

int i = 0

for (i = 0i <MAX_NUMi++) {

if (client[i].sockfd != -1 &&strcmp(client[i].name, name) == 0)

return client[i].sockfd

}

return 0

}

//TO

void sendto_one(c_client *p_client, char *buf) {

int i = 0

char sendbuf[1024] = { 0 }

char name[20] = { 0 }

char *p = strtok(buf + 4, "\r\n")//TO\r\n

4

个字符后取出

\r\n

前的名字

strcpy(name, p)

int sock = findname(name)

if (!sock) {

sprintf(sendbuf, "ERROR2\r\n%s

用户不存在

\r\n\r\n", name)

send(p_client->sockfd, sendbuf, strlen(sendbuf), 0)

} else {

sprintf(sendbuf, "FROM\r\n%s\r\n%s", p_client->name, buf + 4 + strlen(

name) + 2)

if(send(sock, sendbuf, strlen(sendbuf), 0)<=0){

printf("send errrrrr\n")

exit(1)

}

}

}

void pthread_fun(void* cclient)

//quit

void quit(c_client *p_client){

int i=0

int idx

char buf[1024] = {0}

c_client_c *temp

printf("--%s

退出聊天室

\n",p_client->name)

close(p_client->sockfd)

p_client->sockfd = -1

p_client->pid = -1

p_client->flg = -1

sprintf(buf,"NOTICE1\r\n%s

退出聊天室

\r\n\r\n",p_client->name)

memset(p_client->name,0,20)

for(i=0i<MAX_NUMi++){

if(client[i].sockfd != -1 &&client[i].flg != -1)

send(client[i].sockfd,buf,strlen(buf),0)

}

if(head != NULL &&head->next != NULL){

memset(buf,0,1024)

pthread_rwlock_rdlock(&idx_lock)

idx = find_fd(client)

pthread_rwlock_unlock(&idx_lock)

client[idx].sockfd = head->next->sockfd

pthread_rwlock_wrlock(&wait_lock)

temp = head->next

head->next = head->next->next

free(temp)

pthread_rwlock_unlock(&wait_lock)

sprintf(buf,"NOTICE\r\n

您已被唤醒

,

请继续 *** 作

\r\n\r\n")

send(client[idx].sockfd,buf,strlen(buf),0)

if

(pthread_create(&client[idx].pid,

NULL,

(void

*)pthread_fun,(void

*)

&client[idx]) != 0) {

perror("pthread_create")

exit(1)

}

pthread_detach(client[idx].pid)

}

}

void pthread_fun(void* cclient) {

c_client *p_client = (c_client *) cclient

char buf[MAX_SIZE] = { 0 }

char sendbuf[1024] = { 0 }

int i, n

char *p

sprintf(sendbuf, "%s", "NOTICE\r\n

通讯通道开启

\r\n\r\n")

if (send(p_client->sockfd, sendbuf, strlen(sendbuf), 0) <= 0) {

printf("send err\n")

}

memset(sendbuf, 0, 1024)

while (1) {

memset(buf, 0, MAX_SIZE)

n = recv(p_client->sockfd, buf, sizeof(buf) - 1, MSG_NOSIGNAL)

if (n <= 0) {

close(p_client->sockfd)

p_client->sockfd = -1

break

}

if (logform(buf)) {

if (cmpname(buf, p_client) == 0) {

send(p_client->sockfd, "ERROR\r\n

用户名重复

\r\n\r\n", 26, 0)

continue

} else {

p_client->flg = 1

p = strtok(buf + 7, "\r\n\r\n")

strcpy(p_client->name, p)

sprintf(sendbuf, "100\r\n%s\r\n\r\n", p_client->name)

send(p_client->sockfd, sendbuf, sizeof(sendbuf), 0)

printf("%s

进入聊天室

\n", p_client->name)

for (i = 0i <MAX_NUMi++) {

if (client[i].sockfd != -1 &&client[i].sockfd

!= p_client->sockfd &&client[i].flg != -1)

send(client[i].sockfd, sendbuf, sizeof(sendbuf), 0)

/*服务器*/

#include <stdio.h>

#include <stdlib.h>

#include <errno.h>

#include <string.h>

#include <sys/types.h>

#include <netinet/in.h>

#include <sys/socket.h>

#include <sys/wait.h>

#define SERVPORT 5555

#define BACKLOG 10

#define MAX(a,b) ((a)>(b)?(a):(b))

void str_echo(int)

void server()

{

int sockfd,client_fd

struct sockaddr_in my_addr

struct sockaddr_in remote_addr

socklen_t sin_size

if((sockfd=socket(AF_INET,SOCK_STREAM,0))== -1)

{

perror("socket create error!")

exit(1)

}

my_addr.sin_family=AF_INET

my_addr.sin_port=htons(SERVPORT)

my_addr.sin_addr.s_addr=INADDR_ANY

bzero(&(my_addr.sin_zero),8)

if(bind(sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))==-1)

{

perror("bind error!")

exit(1)

}

if(listen(sockfd,BACKLOG)==-1)

{

perror("listen error!")

exit(1)

}

while(1)

{

sin_size=sizeof(struct sockaddr_in)

if((client_fd=accept(sockfd,(struct sockaddr *)&remote_addr,&sin_size))==-1)

{

perror("accept error!")

continue

}

printf("received a connection from %s\n",inet_ntoa(remote_addr.sin_addr))

if(!fork())

{

close(sockfd)

str_echo(client_fd)

exit(0)

}

close(client_fd)

}

}

void str_echo(int sockfd)

{

int maxfd

char sendbuf[1024]={0}

char recvbuf[1024]={0}

fd_set rfds

while(1)

{

FD_SET(0,&rfds)

FD_SET(sockfd,&rfds)

maxfd=MAX(0,sockfd)+1

select(maxfd,&rfds,NULL,NULL,NULL)

if(FD_ISSET(sockfd,&rfds))

{

bzero(recvbuf,1024)

recv(sockfd,recvbuf,1024,0)

printf("C:%s\n",recvbuf)

}

if(FD_ISSET(0,&rfds))

{

read(0,sendbuf,1024)

send(sockfd,sendbuf,strlen(sendbuf),0)

bzero(sendbuf,1024)

}

}

}

int main()

{

server()

return 0

}

/*客户端*/

#include <stdio.h>

#include <stdlib.h>

#include <errno.h>

#include <string.h>

#include <netdb.h>

#include <sys/types.h>

#include <netinet/in.h>

#include <sys/socket.h>

#define SERVPORT 5555

#define MAXSIZE 1024

#define MAX(a,b) ((a)>(b)?(a):(b))

void client(int argc,char **argv)

{

int sockfd,maxfd

char sendbuf[MAXSIZE]={0}

char recvbuf[MAXSIZE]={0}

// struct hostent *host

struct sockaddr_in serv_addr

fd_set rfds

/* if(argc<2)

{

fprintf(stderr,"Please enter the sserver's name!\n")

exit(1)

}

if((host=gethostbyname(argv[1]))==NULL)

{

herror("get host by name error!\n")

exit(1)

}

*/

if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)

{

perror("socket creat error!\n")

exit(1)

}

serv_addr.sin_family=AF_INET

serv_addr.sin_port=htons(SERVPORT)

// serv_addr.sin_addr=*((struct in_addr *)host->h_addr)

serv_addr.sin_addr.s_addr=inet_addr("127.0.0.1")

bzero(&(serv_addr.sin_zero),8)

if(connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(struct sockaddr))==-1)

{

perror("connection error!\n")

exit(1)

}

FD_ZERO(&rfds)

while(1)

{

FD_SET(0,&rfds)

FD_SET(sockfd,&rfds)

maxfd=MAX(0,sockfd)+1

select(maxfd,&rfds,NULL,NULL,NULL)

if(FD_ISSET(sockfd,&rfds))

{

bzero(recvbuf,MAXSIZE)

recv(sockfd,recvbuf,MAXSIZE,0)

printf("S:%s\n",recvbuf)

}

if(FD_ISSET(0,&rfds))

{

fgets(sendbuf,MAXSIZE,stdin)

send(sockfd,sendbuf,strlen(sendbuf),0)

bzero(sendbuf,MAXSIZE)

}

}

// close(sockfd)

}

int main(int argc,char **argv)

{

client(argc,argv)

return 0

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/8972557.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-23
下一篇 2023-04-23

发表评论

登录后才能评论

评论列表(0条)

保存