在linux下如何用c语言来写一个socket编程的聊天小程序

在linux下如何用c语言来写一个socket编程的聊天小程序,第1张

源码如下:

//chat_one.c

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <stdio.h>

#include <string.h>

#include <errno.h>

#include <malloc.h>

#include <sys/select.h>

int main( int argc, char **argv)

{

struct sockaddr_in chatone, chattwo

char pmsg[1000]

char *buf

intchatone_fd

intret,i

intlen, msg_len

fd_set fdset

if ( argc <2 ){

printf("please input ip address\n")

return -1

}

printf("server address is %s\n", argv[1])

chattwo.sin_family = AF_INET

chattwo.sin_port = htons(60002)

inet_pton(AF_INET, argv[1], &chattwo.sin_addr.s_addr)

chatone.sin_family = AF_INET

chatone.sin_port = htons(60000)

chatone.sin_addr.s_addr = INADDR_ANY

chatone_fd = socket(PF_INET, SOCK_DGRAM, 0)

if ( -1 == chatone_fd ){

printf("create socket failed %s\n", strerror(errno))

return -1

}

ret = bind(chatone_fd, (struct sockaddr *)&chatone, sizeof(chatone))

if ( -1 == ret){

printf("bind failed %s \n", strerror(errno))

return -1

}

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

FD_ZERO( &fdset )

FD_SET ( 0, &fdset)

FD_SET( chatone_fd, &fdset)

if ( -1 == select ( chatone_fd+1, &fdset, NULL, NULL, NULL) ){

continue

}

if ( FD_ISSET( chatone_fd, &fdset)){

recvfrom( chatone_fd, pmsg, 999, 0, NULL, 0)

printf("receive %s\n", pmsg)

}

else{

memset( pmsg, 0, 1000)

fgets(pmsg, 999, stdin)

len = sizeof(chattwo)

sendto( chatone_fd, pmsg, 1000, 0,\

(struct sockaddr*) &chattwo, len)

printf("send %s\n", pmsg)

}

}

printf("sent %d packets\n", i)

close(chatone_fd)

return 0

}

//chat_two.c

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <stdio.h>

#include <string.h>

#include <errno.h>

#include <malloc.h>

#include <sys/select.h>

int main( int argc, char **argv)

{

struct sockaddr_in chatone, chattwo

char pmsg[1000]

char *buf

intchattwo_fd

intret,i

intlen, msg_len

fd_set fdset

if ( argc <2 ){

printf("please input ip address\n")

return -1

}

printf("server address is %s\n", argv[1])

chattwo.sin_family = AF_INET

chattwo.sin_port = htons(60002)

chattwo.sin_addr.s_addr = INADDR_ANY

chatone.sin_family = AF_INET

chatone.sin_port = htons(60000)

inet_pton(AF_INET, argv[1], &chatone.sin_addr.s_addr)

chattwo_fd = socket(PF_INET, SOCK_DGRAM, 0)

if ( -1 == chattwo_fd ){

printf("create socket failed %s\n", strerror(errno))

return -1

}

ret = bind(chattwo_fd, (struct sockaddr *)&chattwo, sizeof(chattwo))

if ( -1 == ret){

printf("bind failed %s \n", strerror(errno))

return -1

}

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

FD_ZERO( &fdset )

FD_SET ( 0, &fdset)

FD_SET( chattwo_fd, &fdset)

if ( -1 == select ( chattwo_fd+1, &fdset, NULL, NULL, NULL) ){

continue

}

if ( FD_ISSET( chattwo_fd, &fdset)){

recvfrom( chattwo_fd, pmsg, 999, 0, NULL, 0)

printf("receive: %s\n", pmsg)

}

else{

memset( pmsg, 0, 1000)

fgets(pmsg, 999, stdin)

len = sizeof(chatone)

sendto( chattwo_fd, pmsg, 1000, 0,\

(struct sockaddr*) &chatone, len)

printf("send %s\n", pmsg)

}

}

printf("sent %d packets\n", i)

close(chattwo_fd)

return 0

}

编译好这个两个程序就可以进行简单的通信了。

//下面是一个实例

/**    

* socket.io chat    

*    

*/    

     

var web = require('QuickWeb')    

     

// undefined    

var _ = undefined     

     

/**    

 * 创建一个房间    

 *    

 * @param {string} room 房间名称    

 * @param {socket.io} io socket.io实例    

 */    

var Room = module.exports = function (room, io) {    

// 初始化socket.io实例,仅在第一次创建房间时需要设置io参数    

if (typeof io != 'undefined')    

Room.prototype.io = io    

var io = this.io    

   

// 房间成员列表    

var nicknames = this.nicknames = {}    

var onlinesum = this.onlinesum = 0    

   

// 握手验证,如果是登录用户,则自动获取其昵称    

io.set('authorization', function (handshakeData, callback) {    

// 通过客户端的cookie字符串来获取其session数据    

var sessionObject = handshakeData.sessionObject = web.session.getByCookie(handshakeData.headers.cookie)    

   

// 如果不是登录用户,则自动为其设置一个昵称    

var nickname = sessionObject.data.nickname    

if (typeof nickname != 'string' || nickname == '')    

nickname = '#' + Math.floor(Math.random() * 1000) + '' + (new Date().getTime() % 86400000)    

sessionObject.data.nickname = nickname    

   

callback(null, true)    

})    

   

/** 连接处理 */    

var connectionHandle = function (socket) {    

onlinesum++    

// 获取session    

var session = socket.handshake.sessionObject.data    

var nickname = session.nickname    

   

// 保持session,以免session过期    

var hold_session = socket.handshake.sessionObject.hold    

   

/** 刷新在线列表 */    

refresh_online = function () {    

var n = []    

for (var i in nicknames)    

n.push(i)    

socket.broadcast.emit('online list', n)    

socket.emit('online list', n)    

}    

   

// 新成员加入时,通知其他成员    

nicknames[nickname] = socket    

refresh_online()    

socket.broadcast.emit('system message', nickname + '回来了,大家赶紧去喷他~~')    

   

/** 公共消息 */    

socket.on('public message', function (msg, cb) {    

hold_session()    

var timestamp = new Date().getTime()    

socket.broadcast.emit('public message', nickname, msg, timestamp)    

cb()    

})    

   

/** 私人消息 */    

socket.on('private message', function (to, msg, cb) {    

hold_session()    

var timestamp = new Date().getTime()    

var err = ''    

for (var i in to) {    

var target = nicknames[to[i]]    

if (target) {    

cb()    

target.emit('private message', nickname, msg, timestamp)    

}    

else {    

err += '“' + to[i] + '”不在线\n'    

}    

}    

if (err != '')    

cb(err)    

})    

   

/** 断开来连接 */    

socket.on('disconnect', function () {    

delete nicknames[nickname]    

onlinesum--    

socket.broadcast.emit('system message', nickname + '悄悄地离开了。。。')    

refresh_online()    

})    

   

/** 命令 */    

socket.on('command', function (args, cb) {    

if (args.length < 1) {    

cb('无效的命令')    

return    

}    

switch (args[0]) {    

/* 查询或更改昵称 */    

case 'nick':    

var nick = args[1]    

if (typeof nick == 'undefined')    

cb(_, '你的昵称是:' + nickname)    

else    

if (nick == nickname)    

cb('你的昵称本来就是“' + nick + '”嘛,不需要改')    

else if (nicknameIsUsed(nick))    

cb('昵称“' + nick + '”已被占用')    

else {    

nicknames[nick] = nicknames[nickname]    

delete nicknames[nickname]    

var oldnick = nickname    

session.nickname = nickname = nick    

cb(_, '昵称已更改为“' + nick + '”')    

// 通知其他人    

refresh_online()    

socket.broadcast.emit('system message', '“' + oldnick + '”的昵称已改为“' + nick + '”')    

}    

break    

   

/* 在线人数 */    

case 'online':    

cb(_, '当前共有' + onlinesum + '个人在线')    

break    

   

/* 帮助 */    

default:    

cb(_, strHelp)    

}    

})    

}    

   

/* 注册聊天室 */    

if (typeof room == 'undefined')    

room = ''    

io.of('/' + room).on('connection', connectionHandle)    

   

   

/** 检查昵称是否被占用 */    

var nicknameIsUsed = function (nickname) {    

for (var i in nicknames)    

if (i == nickname)    

return true    

return false    

}    

}    

   

var strHelp = '输入$help获取帮助\n\    

========= 系统命令 ========\n\    

**$nick** [昵称] 查看或更改昵称\n\    

**$online** 当前在线人数\n\    

**$clear** 清空消息\n\    

========= 使用技巧 ========\n\    

**给某人发送消息** @对方昵称 消息内容(可同时@多个人)\n\    

**发送图片** !图片url\n\    

**发送链接** [网址]\n\    

'


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

原文地址:https://54852.com/yw/11060212.html

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

发表评论

登录后才能评论

评论列表(0条)

    保存