04Socket网络编程的服务器写法

  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Data;
  5 using System.Drawing;
  6 using System.Linq;
  7 using System.Net;
  8 using System.Net.Sockets;
  9 using System.Text;
 10 using System.Threading;
 11 using System.Threading.Tasks;
 12 using System.Windows.Forms;
 13
 14 namespace _02ChatServer
 15 {
 16     public partial class ChatServer : Form
 17     {
 18         public ChatServer()
 19         {
 20             Control.CheckForIllegalCrossThreadCalls = false;
 21             InitializeComponent();
 22         }
 23         Socket skListen = null;//为了服务器能够控制监听的停止,把监听的socket声明在外面.
 24         Dictionary<string, Socket> dicClient = new Dictionary<string, Socket>();
 25         private void button1_Click(object sender, EventArgs e)
 26         {
 27             if (skListen == null)
 28             {
 29                 //开启一个Socket进行监听通讯的端口
 30                 skListen = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
 31             }
 32             //绑定IP和端口号
 33             skListen.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9999));
 34             //设置监听的队列
 35             skListen.Listen(10);
 36             lblState.ForeColor = Color.Green;
 37             lblState.Font = new Font("黑体", 30);
 38             lblState.Text = "监听中..";
 39
 40
 41
 42             Thread thread = new Thread(new ThreadStart(() => {
 43                 //不断接收用户的连接请求.
 44                 while (true)
 45                 {
 46                     //准备客户端的连接;
 47                     Socket skConnetion = skListen.Accept();//这句话会阻塞主线程,所以要把他放在一个单独的线程中.
 48                     //当客户端连接的时候将IP端口号和Socket帮定到一个集合中
 49                     dicClient.Add(skConnetion.RemoteEndPoint.ToString(), skConnetion);
 50                     listboxClients.Items.Add( skConnetion.RemoteEndPoint.ToString());
 51                     txtLog.AppendText(skConnetion.RemoteEndPoint.ToString() + "已经连接上了.."+Environment.NewLine);
 52                     //当一个用户连接上的时候如果不发送消息的时候就会阻塞当前线程所有要再创建一个线程来接收用户的消息.
 53                     //使用线程池来创建一个线程执行客户端接收用户消息,下面的lamada表达式通过传入客户端的连接socket来实现函数的内部访问客户端连接的socket,当传入的不是lanmeda表达式的时候可以使用这种方法传入客户端socket.
 54                     ThreadPool.QueueUserWorkItem(new WaitCallback(obj=>{
 55                         Socket skReceive = skConnetion as Socket;
 56
 57                         byte[] buffer=new byte[1024 * 1024 * 4];
 58                        //因为客户端发送的消息不是只发一个,要不断的重复接收用户的信息发送
 59                         while (true)
 60                         {
 61
 62                            int count= skReceive.Receive(buffer);
 63                            if (count == 0)
 64                            {
 65                                //用户退出了
 66                                txtLog.AppendText("客户端"+skReceive.RemoteEndPoint.ToString()+"已退出");
 67                                dicClient.Remove(skReceive.RemoteEndPoint.ToString());
 68                                listboxClients.Items.Remove(skReceive.RemoteEndPoint.ToString());
 69                                break;
 70                            }
 71                            string msg = Encoding.UTF8.GetString(buffer,0,count);
 72                            txtLog.AppendText("客户端"+skConnetion.RemoteEndPoint.ToString()+"发来消息:"+msg+Environment.NewLine);//易外耳门特
 73                         }
 74
 75                     }),skConnetion);
 76                 }
 77
 78             }));
 79             thread.IsBackground = true;
 80             thread.Start();
 81
 82
 83         }
 84
 85         private void button3_Click(object sender, EventArgs e)
 86         {
 87             //判断是否选中了要通讯的ip端口
 88             if (listboxClients.SelectedItem != null)
 89             {
 90                 //根据用户的选中的端口,找到通讯的scoket
 91                 Socket sk = dicClient[listboxClients.SelectedItem.ToString()];
 92                 if (sk != null)
 93                 {
 94                     //把用户输入的消息转化成字节数组
 95                     byte[] buffer = Encoding.UTF8.GetBytes(txtSendMsg.Text.Trim());
 96                     byte[] sendBuffer=new byte[buffer.Length+1];
 97
 98                     Buffer.BlockCopy(buffer, 0, sendBuffer, 1, buffer.Length);
 99                     //向客户端发送了消息
100                     sk.Send(sendBuffer);
101                     //写入日志
102                     txtLog.AppendText("服务器向[" + listboxClients.SelectedItem.ToString() + "]发送了:" + txtSendMsg.Text + Environment.NewLine);
103                 }
104             }
105             else
106             {
107                 MessageBox.Show("请选中要发送消息的客户端");
108             }
109         }
110
111         private void button4_Click(object sender, EventArgs e)
112         {
113             if (listboxClients.SelectedItem != null)
114             {
115                 //1.根据选中的客户端端口ip选择通讯的socket
116                Socket skClient=  dicClient[listboxClients.SelectedItem.ToString()];
117                skClient.Send(new byte[] { 2 });//发送一个标记2来提示客户端发送的是一个闪屏
118
119             }
120             else
121             {
122                 MessageBox.Show("请选择要发送的客户端");
123             }
124         }
125     }
126 }
时间: 2024-10-29 10:47:54

04Socket网络编程的服务器写法的相关文章

[python网络编程]DNS服务器

在上一篇中,使用scrapy修改源IP发送请求的最后我们提到由于hosts文件不支持正则,会导致我们的随机域名DNS查询失败.使用DNS代理服务器可以解决这个问题, 下面是我用gevent写的小工具,很简单.我们只拦截匹配的A记录,然后发送DNS Response,如果不匹配,那么我们服务器就是一个DNS代理,转发请求. # -*- coding=utf-8 -*- import struct from cStringIO import StringIO from collections imp

Linux网络编程客户\服务器设计范式

1.前言 网络编程分为客户端和服务端,服务器通常分为迭代服务器和并发服务器.并发服务器可以根据多进程或多线程进行细分,给每个连接创建一个独立的进程或线程,或者预先分配好多个进程或线程等待连接的请求.今天探讨三种设计范式 (1)迭代服务器 (2)并发服务器,为每个客户请求创建一个进程或线程 (3)预先分配子进程或线程,每个子进程或线程调用accept 3.测试用例: 客户端代码: 1 #include <sys/wait.h> 2 #include <string.h> 3 #inc

Linux 网络编程——并发服务器的三种实现模型

服务器设计技术有很多,按使用的协议来分有 TCP 服务器和 UDP 服务器,按处理方式来分有循环服务器和并发服务器. 循环服务器与并发服务器模型 在网络程序里面,一般来说都是许多客户对应一个服务器(多对一),为了处理客户的请求,对服务端的程序就提出了特殊的要求. 目前最常用的服务器模型有: ·循环服务器:服务器在同一时刻只能响应一个客户端的请求 ·并发服务器:服务器在同一时刻可以响应多个客户端的请求 UDP 循环服务器的实现方法 UDP 循环服务器每次从套接字上读取一个客户端的请求 -> 处理

UNIX网络编程——客户/服务器心搏函数 (转)

下面是关于回送客户和服务器程序开发一些简单的心搏函数.这些函数可以发现对端主机或到对端的通信路径的过早失效.         在给出这些函数之前我们必须提出一些警告.首先,有人会想到使用TCP的保持存活特性(SO_KEEPALIVE套接字选项)来提供这种功能,然而TCP得在连接已经闲置2小时之后才发送一个保持存活探测段.意识到这一点以后,他们的下一个问题是如何把保持存活参数改为一个小得多的值(往往是在秒钟的量级),以便更快的检测到失效.尽管缩短TCP的保持存活定时器参数在许多系统上确实可行,但是

Python网络编程UDP服务器与客服端简单例子

[转载] https://blog.csdn.net/hu330459076/article/details/7868028 UDP服务器代码: #!/usr/bin/env python # -*- coding:UTF-8 -*- from socket import * from time import ctime HOST = '127.0.0.1' PORT = 21567 BUFSIZE = 1024 ADDR = (HOST,PORT) udpSerSock = socket(AF

linux网络编程echo服务器

echo_server #include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <sys/socket.h>#include <www.qixoo.qixoo.com/sys/types.h>#include <signal.h>#include <memory.h>#include <errno.h>#include <netin

Linux网络编程入门 (转载)

http://www.cnblogs.com/RascallySnake/archive/2012/01/04/2312564.html (一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍客户端和服务端         网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客户端        在网络程序中,如果一个程序主动和外面的程序通信,那么我们把这个程序称为客户端程序. 比如我们使用ftp程序从另外一        个地方获取文件

Linux网络编程入门

(一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍 客户端和服务端 网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客户端 在网络程序中,如果一个程序主动和外面的程序通信,那么我们把这个程序称为客户端程序. 比如我们使用ftp程序从另外一 个地方获取文件的时候,是我们的ftp程序主动同外面进行通信(获取文件), 所以这个地方我们的ftp程序就是客户端程序. 服务端 和客户端相对应的程序即为服务端程序.被动的等待外面的程序来和自己通

Java网络编程 探险

我们先来看看计算机网络主要功能:资源共享:信息传输和集中处理:负载均衡和分布处理:综合信息服务. 实际上Java的网络编程就是服务器通过ServerSocket建立监听,客户端通过Socket连接到指定服务器后,通信双方就可以通过IO流进行通信了. 1.认识网络编程 计算机网络中实现通信的约定被称为通信协议,通信协议负责对传输速率.传输代码.代码结构.传输控制步骤.出错控制等制定处理标准. 计算机网络的OSI模型(各种计算机网络的参考标准)如下: 1)上层协议 http,ftp,https 2)